在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法。我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于。同时我们也知道equals也可以判断两个对象是否相等,那么他们两者之间是否存在关联关系呢?

public class Student implements Comparable<Student>{
private String id;
private String name;
private int age; public Student(String id,String name,int age){
this.id = id;
this.name = name;
this.age = age;
} public boolean equals(Object obj){
if(obj == null){
return false;
} if(this == obj){
return true;
} if(obj.getClass() != this.getClass()){
return false;
} Student student = (Student)obj;
if(!student.getName().equals(getName())){
return false;
} return true;
} public int compareTo(Student student) {
return this.age - student.age;
} /** 省略getter、setter方法 */
}

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)); Collections.sort(list); //排序 Student student = new Student("2", "chenssy1", 26); //检索student在list中的位置
int index1 = list.indexOf(student);
int index2 = Collections.binarySearch(list, student); System.out.println("index1 = " + index1);
System.out.println("index2 = " + index2);
}

按照常规思路来说应该两者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方法,同时还需要确保两个方法同步。

集合之保持compareTo和equals同步的更多相关文章

  1. Java集合之保持compareTo和equals同步

    在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法.我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于.同时我们也知道e ...

  2. Java提高篇(三八)-----Java集合细节(四):保持compareTo和equals同步

    在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法.我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于.同时我们也知道e ...

  3. [改善Java代码]集合中的元素必须做到compareTo和equals同步

    实现了Comparable接口的元素就可以排序,

  4. 比较compareTo与equals及==的区别

    1.compareTo: 附上:源码: public int compareTo(String anotherString) {         int len1 = value.length;   ...

  5. Java中“==”、“compareTo()”和“equals()”的区别

    在比较两个对象或者数据大小的时候,经常会用到==.compareTo()和equals(),尤其是在接入了Comparable接口后重写compareTo方法等场景,所以我们来理一下这三个的区别. 1 ...

  6. (转)C# 的 String.CompareTo、 Equals和==的比较

    String.CompareTo 语法 public int CompareTo(    string strB) 返回值 小于 0,实例小于参数 strB: 0,实例等于参数 strB: 大于 0, ...

  7. List集合去除重复对象及equals()、hashCode()方法的作用

    原文:https://blog.csdn.net/freelander_j/article/details/52211010 在java中,要将一个集合中重复的对象除去,如果这个集合中的数据类型是基本 ...

  8. 比较运算符compareTo()、equals()、==之间的区别

    前言 首先再次强调hashcode (==)和equals的真正含义(我记得以前有人会说,equals是判断对象内容,hashcode是判断是否相等之类): equals:是否同一个对象实例.注意,是 ...

  9. 比较运算符compareTo()、equals()、==之间的区别与应用总结

    在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配 ...

随机推荐

  1. jquery 对象的 height、innerHeight、outerHeight 的区别以及DOM 元素的 clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop

    前言:jquery 对象的 height.innerHeight.outerHeight,还有 DOM 元素的 clientHeight.offsetHeight.scrollHeight.offse ...

  2. Code Signal_练习题_Sort by Height

    Some people are standing in a row in a park. There are trees between them which cannot be moved. You ...

  3. LAMP创建

    httpd yum install httpd -y systemctl status httpd systemctl start httpd systemctl stop firewalld Mar ...

  4. 【CVE-2018-11116】openwrt rpcd 配置文件错误导致访问控制失效

    User can access to ubus over HTTP. This way depend on rpcd service. When misconfigure the rpcd's ACL ...

  5. Android ListView几个重要属性

    1.transciptMode属性,需要用ListView或者其它显示大量Items的控件实时跟踪或者查看信息,并且希望最新的条目可以自动滚动到可视范围内.通过设置的控件transcriptMode属 ...

  6. CSS 内外边距 float positio属性

    一.外边距和内边 margin:            用于控制元素与元素之间的距离 外边距:margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的. padding:   ...

  7. Typescript 接口(interface)

    概述 typescript 的接口只会关注值的外形,实际就是类型(条件)的检查,只要满足就是被允许的. 接口描述了类的公共部分. 接口 interface Person { firstName: st ...

  8. 初探diskstats

    内核很多重要子系统均通过proc文件的方式,将自身的一些统计信息输出,方便最终用户查看各子系统的运行状态,这些统计信息被称为metrics. 直接查看metrics并不能获取到有用的信息,一般都是由特 ...

  9. d3js path generator vs layouts

    我们知道d3的一般套路就是d3.selectAll('path.mypath').data(yourDataset).enter().append('path').attr('class','mypa ...

  10. System.Web.Optimization对脚本和样式表的操作

    这个也是本章重点向描述的部分,首先我们可以使用VS2012RC来新建一个MVC4.0项目,版本可以为4.0或4.5.在Global.asax文件代码中,我们发现已经把过滤器,路由器,以及对样式表和脚本 ...