详解java中保持compareTo和equals同步
详解java中保持compareto和equals同步
摘要 : 介绍重写equlas()和comparable接口,两者进行不相同的判断。从而使两者的对应的list.indexof()与 collections.binarysearch()得到的不一样。
在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也应该相等。
细节 : 实现了compareto方法,就有必要实现equals方法,同时还需要确保两个方法同步
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!