摘要 : 介紹重寫equlas()和comparable接口,兩者進行不相同的判斷。從而使兩者的對應的list.indexOf()與 Collections.binarySearch()得到的不一樣。
在Java中我們常使用Comparable接口來實現(xiàn)排序,其中compareTo是實現(xiàn)該接口方法。我們知道compareTo返回0表示兩個對象相等,返回正數(shù)表示大于,返回負數(shù)表示小于。同時我們也知道equals也可以判斷兩個對象是否相等,那么他們兩者之間是否存在關聯(lián)關系呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
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類實現(xiàn)Comparable接口和實現(xiàn)equals方法,其中compareTo是根據(jù)age來比對的,equals是根據(jù)name來比對的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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); } |
按照常規(guī)思路來說應該兩者index是一致的,因為他們檢索的是同一個對象,但是非常遺憾,其運行結(jié)果:
1
2
3
|
index1 = 0 index2 = 1 |
為什么會產(chǎn)生這樣不同的結(jié)果呢?
這是因為indexOf和binarySearch的實現(xiàn)機制不同。
indexOf是基于equals來實現(xiàn)的只要equals返回TRUE就認為已經(jīng)找到了相同的元素。
而binarySearch是基于compareTo方法的,當compareTo返回0 時就認為已經(jīng)找到了該元素。
在我們實現(xiàn)的Student類中我們覆寫了compareTo和equals方法,但是我們的compareTo、equals的比較依據(jù)不同,一個是基于age、一個是基于name。比較依據(jù)不同那么得到的結(jié)果很有可能會不同。
所以知道了原因,我們就好修改了:將兩者之間的比較依據(jù)保持一致即可。
對于compareTo和equals兩個方法我們可以總結(jié)為:compareTo是判斷元素在排序中的位置是否相等,equals是判斷元素是否相等,既然一個決定排序位置,一個決定相等,所以我們非常有必要確保當排序位置相同時,其equals也應該相等。
細節(jié) : 實現(xiàn)了compareTo方法,就有必要實現(xiàn)equals方法,同時還需要確保兩個方法同步
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!