Java提高篇(三八)-----Java集合细节(四):保持compareTo和equals同步
在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法。我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于。同时我们也知道equals也可以判断两个对象是否相等,那么他们两者之间是否存在关联关系呢?
public class Student implements Comparable<Student>{ private String id; private String name; private int age;</span><span style="color: #0000ff">public</span> Student(String id,String name,<span style="color: #0000ff">int</span><span style="color: #000000"> age){ </span><span style="color: #0000ff">this</span>.id =<span style="color: #000000"> id; </span><span style="color: #0000ff">this</span>.name =<span style="color: #000000"> name; </span><span style="color: #0000ff">this</span>.age =<span style="color: #000000"> age; } </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> equals(Object obj){ </span><span style="color: #0000ff">if</span>(obj == <span style="color: #0000ff">null</span><span style="color: #000000">){ </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">; } </span><span style="color: #0000ff">if</span>(<span style="color: #0000ff">this</span> ==<span style="color: #000000"> obj){ </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; } </span><span style="color: #0000ff">if</span>(obj.getClass() != <span style="color: #0000ff">this</span><span style="color: #000000">.getClass()){ </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">; } Student student </span>=<span style="color: #000000"> (Student)obj; </span><span style="color: #0000ff">if</span>(!<span style="color: #000000">student.getName().equals(getName())){ </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">; } </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; } </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span><span style="color: #000000"> compareTo(Student student) { </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.age -<span style="color: #000000"> student.age; } </span><span style="color: #008000">/**</span><span style="color: #008000"> 省略getter、setter方法 </span><span style="color: #008000">*/</span><span style="color: #000000">
}
Student类实现Comparable接口和实现equals方法,其中compareTo是根据age来比对的,equals是根据name来比对的。
public static void main(String[] args){ List<Student> list = new ArrayList<>(); list.add(new Student("1", "chenssy1", 24)); list.add(new Student("2", "chenssy1", 26));Student student = new Student("2", "chenssy1", 26);Collections.sort(list); </span><span style="color: #008000">//</span><span style="color: #008000">排序</span>
</span><span style="color: #008000">//</span><span style="color: #008000">检索student在list中的位置</span> <span style="color: #0000ff">int</span> index1 =<span style="color: #000000"> list.indexOf(student); </span><span style="color: #0000ff">int</span> index2 =<span style="color: #000000"> Collections.binarySearch(list, student); System.out.println(</span>"index1 = " +<span style="color: #000000"> index1); System.out.println(</span>"index2 = " +<span style="color: #000000"> index2); }</span></pre>
按照常规思路来说应该两者index是一致的,因为他们检索的是同一个对象,但是非常遗憾,其运行结果:
index1 = 0
index2 = 1
为什么会产生这样不同的结果呢?这是因为indexOf和binarySearch的实现机制不同,indexOf是基于equals来实现的只要equals返回TRUE就认为已经找到了相同的元素。而binarySearch是基于compareTo方法的,当compareTo返回0 时就认为已经找到了该元素。在我们实现的Student类中我们覆写了compareTo和equals方法,但是我们的compareTo、equals的比较依据不同,一个是基于age、一个是基于name。比较依据不同那么得到的结果很有可能会不同。所以知道了原因,我们就好修改了:将两者之间的比较依据保持一致即可。
对于compareTo和equals两个方法我们可以总结为:compareTo是判断元素在排序中的位置是否相等,equals是判断元素是否相等,既然一个决定排序位置,一个决定相等,所以我们非常有必要确保当排序位置相同时,其equals也应该相等。
细节(4.1):实现了compareTo方法,就有必要实现equals方法,同时还需要确保两个方法同步。
参考文献:编写高质量代码:改善Java程序的151个建议
-----原文出自:http://cmsblogs.com/?p=1242,请尊重作者辛勤劳动成果,转载说明出处.
-----个人站点:http://cmsblogs.com
-
作者:chenssy。一个专注于【死磕 Java】系列创作的男人
出处:https://www.cnblogs.com/chenssy/p/3895471.html
作者个人网站:https://www.cmsblogs.com/。专注于 Java 优质系列文章分享,提供一站式 Java 学习资料
目前死磕系列包括:
1. 【死磕 Java 并发】:https://www.cmsblogs.com/category/1391296887813967872(已完成)
2.【死磕 Spring 之 IOC】:https://www.cmsblogs.com/category/1391374860344758272(已完成)
3.【死磕 Redis】:https://www.cmsblogs.com/category/1391389927996002304(已完成)
4.【死磕 Java 基础】:https://www.cmsblogs.com/category/1411518540095295488
5.【死磕 NIO】:https://www.cmsblogs.com/article/1435620402348036096
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。