大家好,今天来为大家分享深入解析Comparable与Comparator接口:Java中对象比较的奥秘的一些知识点,和的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!
虽然这两个界面看起来很相似,但使用方法却截然不同。下面我就开始介绍这两个接口以及它们的一些应用场景。
接口名包main function Comparablejava.langintcompareTo(T o) (比较本对象和指定对象的顺序) Comparatorjava.utilintcompare(T o1,T o2) (比较用于排序的两个参数), boolean equals(Object obj ) (表示其他对象是否与此Comparator “相等”)
一、Comparable接口
public interface Comparable 以下介绍来自官方文档:
该接口强制实现它的每个类的对象的整体排序。这种排序称为类的自然排序,类的compareTo方法称为其自然比较方法。
实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)自动排序。该接口的实现者可以用作有序映射(实现了SortedMap接口的对象)或有序集合(实现了SortedSet接口的对象)中的元素,而无需指定比较器。
建议(虽然不是必需的)自然排序最好和equals一致。
所谓与equals一致的自然排序是指A类的自然排序。对于每个o1和o2,当且仅当(o1.compareTo(o2))和o1.equals(o2)具有相同的布尔值, A类排序的自然顺序称为与equals一致。
下面将文档中出现的几个点抽出来单独理解:自然排序:Comparable 接口强制对实现它的类的对象进行整体排序。这种排序称为类的自然排序;自然排序与equals 一致: A 类对于每个o1 和o2,当和仅当( o1.compareTo( o2 ) ) 和o1.equals( o2 ) 具有相同的布尔值。
方法详细信息:
intcompareTo(T o) 比较此对象与指定对象的顺序。比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
实现类必须确保所有x 和y 都存在关系sgn(x.compareTo(y))==-sgn(y.compareTo(x)) 。 (这意味着如果y.compareTo(x) 抛出异常,x.compareTo(y) 也会抛出异常。)
参数: o - 要比较的对象返回:负整数、零或正整数,具体取决于此对象是否小于、等于或大于指定对象抛出:CalssCastException - 如果指定的类型对象不允许与此对象进行比较通过一个小例子来介绍如何使用Comparable接口:下面是一个普通的Person类,name和age两个属性以及对应的get和set方法。未实现Comparable 接口的Person 类
下面是一个PersonTest测试类以及打印的结果:我们将五个Person对象添加到一个列表中,然后打印出列表的内容。我们发现输出的顺序和加法的顺序是一致的。
测试类打印结果如果我们此时需要按照Person对象的年龄从小到大输出,该如何实现呢?这时候Comparable接口就派上用场了。
我们把Person改造一下,让它实现Comparable接口并重写其compareTo方法:实现Comparable接口的Person类然后在测试类中调用 Collections.sort() 方法对list进行排序之后输出结果:我们可以注意到使用Collections.sortf方法后的结果。事实上,我们在这里明确指定了比较器:Collection.sort()。
但对于实现了SortedMap接口的对象或者实现了SortedSet接口的对象,我们可以在不指定比较器的情况下完成我们需要的功能。
使用实现SortedSet 接口的TreeSet 时无需指定比较器。
二、Comparator接口
公共接口Comparator以下介绍来自官方文档:
强制对对象集合进行整体排序的比较函数。可以将Comparator 传递给排序方法(例如Collections.sort 或Arrays.sort),从而允许精确控制排序顺序。您还可以使用比较器来控制某些数据结构的顺序(例如有序集或有序映射),或为没有自然顺序的对象集合提供排序。
比较器c 强制S 当且仅当对于一组元素S 中的每个e1 和e2,c.compare(e1, e2)==0 和e1.equals(e2) 具有相等的布尔值。的排序称为符合equals的排序。
使用具有与equals 不一致的强制排序功能的比较器对有序集(或有序映射)进行排序时应小心。假设具有显式比较器c 的有序集(或有序映射)与从集合S 中提取的元素(或键)一起使用。如果c 强制对S 进行与equals 不一致的排序,则有序集(或有序映射)将表现“奇怪”。特别是,有序集(或有序映射)将违反根据equals 定义的集合(或映射)的正常契约。
例如,假设使用Comparator c 将两个满足(a.equals(b) c.compare(a, b) !=0) 的元素a 和b 添加到一个空TreeSet 中,则第二次添加操作将返回true (树集的大小会增加)因为从树集的角度来看,a和b不相等,尽管这与Set.add方法的规范相反。
注:通常来说,让Comparator也实现 java.io.Serializable 是一个好主意,因为它们在可序列化的数据结构(像 TreeSet 、TreeMap)中可用作排序方法。为了成功地序列化数据结构,Comparator(如果已提供)必须实现Serializable。
方法详细信息:
int Compare(T o1, To2) 比较用于排序的两个参数。比较用于排序的两个参数。返回负整数、零或正整数,具体取决于第一个参数是小于、等于还是大于第二个参数。
boolean equals(Object obj) 指示某个其他对象是否与此比较器“相等”。指示某个其他对象是否“等于”此比较器。此方法必须遵守Object.equals(Object) 的一般契约。此外,仅当指定对象也是Comparator 并强制执行与此Comparator 相同的排序时,此方法才返回true。因此,comp1.equals(comp2)意味着对于每个对象引用o1和o2,都有sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2))。请注意,不重写Object.equals(Object) 方法始终是安全的。但是,在某些情况下,重写此方法可以通过允许程序确定两个不同的比较器是否强制执行相同的顺序来提高性能。
下面继续使用Person类来说说该如何通过使用Comparator接口来帮助我们实现排序:Person类仍然使用上面没有实现任何接口的Person类。
那么我们如何对Person 类的对象进行排序呢?
****其实只要合理使用Comparator接口即可,如下图:**
通过实现Comparator接口对集合进行排序
现在我们可以来回答下面这个问题了:
TreeSet和TreeMap在排序时如何比较元素? Collections 实用程序类中的sort() 方法如何比较元素?
深入解析Comparable与Comparator接口:Java中对象比较的奥秘的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、深入解析Comparable与Comparator接口:Java中对象比较的奥秘的信息别忘了在本站进行查找哦。
【深入解析Comparable与Comparator接口:Java中对象比较的奥秘】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
学习下 Comparable 和 Comparator 接口,想把项目代码整理得更好结构化一点。
有15位网友表示赞同!
一直在使用 Comparator 排序,今天看了一下 Comparable 的用法,感觉还挺有意思。
有9位网友表示赞同!
原来这两个接口区别还挺大的,Comparable 是对象自身的排序规则,Comparator 可以自定义比较逻辑呢!
有17位网友表示赞同!
刚开始学习 Java 集合的时候就遇到过这两个概念,一直没太理解。这篇文章写的挺好的,解释得清晰易懂。
有11位网友表示赞同!
对想了解对象排序方法的同学,强烈推荐这篇介绍 Comparable 和 Comparator 接口的文章!
有20位网友表示赞同!
以前总是弄混了 Comparable 和 Comparator 的区别,谢谢这位博主帮我理清思路!
有10位网友表示赞同!
这个博客文章内容实用性很强,学习 Java 排序真是受益匪浅。
有12位网友表示赞同!
文章分析的很到位,把重要的知识点都总结清楚了。
有13位网友表示赞同!
感觉在面试的时候这个知识点很有可能被考到,提前了解一下总没错!
有14位网友表示赞同!
java 接口这么重要啊! 比想象中还复杂多变。
有10位网友表示赞同!
做软件开发确实需要不断提升自己的技能和知识面,这篇文章让我有了一定的启发。
有8位网友表示赞同!
最近在写代码的时候也遇到了排序的问题,这篇博客给了我很多帮助。
有12位网友表示赞同!
Java 学习从来都是一个充满挑战的过程!不过遇到这样的认真讲解的文章就更容易理解了。
有6位网友表示赞同!
学习编程果然要细心梳理这些基础知识点。
有5位网友表示赞同!
代码写多了难免会遇到相同的问题,看篇文章可以让我避免重走老路。
有9位网友表示赞同!
这类的技术博客真是太棒了!可以让我持续学习和进步。
有20位网友表示赞同!
希望以后还能看到更多关于 Comparable 和 Comparator 接口的深入探讨!
有19位网友表示赞同!
Java 知识点很多,慢慢积累,一步步提高自己!
有10位网友表示赞同!
这个概念挺容易理解,就是需要实际操作才能真正掌握啊!
有7位网友表示赞同!
文章讲解清晰到位,非常感谢作者的分享!
有10位网友表示赞同!