在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. Implementation:Dijkstra

    #include <iostream> #include <cstdlib> #include <utility> #include <queue> u ...

  2. JS判断客户端是否是iOS或者Android端

    通过判断浏览器的userAgent,用正则来判断手机是否是 IOS 和 Android 客户端. 代码如下: (function(){ var u = navigator.userAgent; var ...

  3. opencv3.2.0图像处理之中值滤波medianBlur API函数

    /*中值滤波:medianBlur函数是非线性滤波 函数原型:void medianBlur(inputArray src,OutputArray dst,int ksize) 参数详解: input ...

  4. (项目积累的)SQL数据库点滴

    最近的的系统用的数据库是mssql,软件mssql 2008 r2 1.存储过程:后勤的综合管理系统(后端内网访问)三层架构配套用的是存储过程,里面列表展示的都是用存储过程,如下: 1)数据库脚本 U ...

  5. Android开发各种Utils收集库

    为方便查找,已进行大致归类,其目录如下所示: Activity相关→ActivityUtils.java→Demo isActivityExists : 判断是否存在Activity launchAc ...

  6. Flutter TabBar

    先看一下Tab的构造方法: TabBar({ Key key, @required this.tabs, this.controller, this.isScrollable: false, this ...

  7. oracle 网络配置 及 pl/sql 连接配置

    oracle网络配置有三个文件,它们都在D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN 这个文件夹下面,有sqlnet.ora.l ...

  8. Nested Prefab Mode 嵌套预制体 保存问题 Dirty

    Unity2018.3 Nested Prefab Mode 嵌套预制体 Unity2018.3开始,新增了一个Prefab Mode,俗称嵌套预制体,在Prefab里套Prefab.实际应用中多少会 ...

  9. SQLSERVER数据库备份操作和还原操作做了什么

    SQLSERVER数据库备份操作和还原操作做了什么 看了这篇文章:还原/备份时做了些什么 自己也测试了一下,下面说的错误日志指的是SQLSERVER ERRORLOG 一般在C:\Program Fi ...

  10. JSP九大内置对象与Servlet的对应关系

    JSP对象                              Servlet中怎样获得 request service方法中的request参数 response service方法中的res ...