JAVA- Comparable接口

Comparable接口概述

Comparable接口一般用於表示某個實例具有內在的排序關係。
對於普通的數值或者字符串,都可以進行一定的排序,但是不能直接給對象進行排序
實際上,之所以我們可以對數值和字符串進行排序,是因為系統內部已經為我們定義了數值和字符串的排序關係。
而我們定義的對象,本身是不包含排序關係的,因此,我們無法直接對對象進行排序。
因此,如果我們需要對對象進行排序的話,就必須定義對象的內在排序關係,即實現Comparable接口。

我們先通過一個實例來看Java中的排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class CollectionsTest {

public static void main(String[] args) {
// TODO Auto-generated method stub
/* 創建一個list集合 */
List list = new ArrayList();
/* 添加學生 */
list.add(1);
list.add(1);
list.add(2);
list.add(3);

/*
* 使用Collections.sort()方法來對集合進行排序
*/
Collections.sort(list);
System.out.println(list);

}

}

程序的輸出結果:[1, 1, 2, 3]

我們再來看另一個程序:

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

class Student {
private Integer sid;
private String sname;

public Student() {
}

public Student(Integer sid, String sname) {
this.sid = sid;
this.sname = sname;
}

public Integer getSid() {
return sid;
}

public void setSid(Integer sid) {
this.sid = sid;
}

public String getSname() {
return sname;
}

public void setSname(String sname) {
this.sname = sname;
}

@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + "]";
}

}

public class ArrayListTest {

public static void main(String[] args) {

/* 創建一個list集合 */
List students = new ArrayList();
/* 添加學生 */
students.add(new Student(1, "Lucy"));
students.add(new Student(1, "Krystal"));
students.add(new Student(2, "Amy"));
students.add(new Student(3, "Adam"));

/* 使用Collections.sort()方法來對集合進行排序 */
Collections.sort(students);
System.out.println(students);

}

}

程序的輸出結果報錯,但系統要求我們的程序實現一個Comparable接口

原因為:基本數據類型和String、Integer等java提供的數據類型系統已經實現了Comparable接口,但是我們自定義的類型並沒有實現Comparable接口,所有第一個程序運行正確,而第二個程序運行就報錯了。

為什麼要使用Comparable接口?

1:用戶自定義的類型對象之間沒有比較的標準,Java語言本身也沒有提供,所以如果一個容器中含有用戶自定義類型數據,並需要對容器中元素進行排序,或查找某一個元素時,我們必須要製定容器中元素與元素之間的比較標準,而製定這個比較標準的最佳實踐就是實現Comparable接口。

如何實現Comparable接口?

1:實現Comparable接口一定要重寫該接口中的compareTo(Object obj)方法。

該方法的比較原理:

首先我們要知道我們比較的是這對象(當前對象)和被比較的對象。
其中,

  • 0表示兩者相等 (返回0表示this == obj)
  • -1表示當前對象排在被比較對象之前(返回正數表示this > obj)
  • 1表示當前對象排在被比較對象之後(返回數表示this < obj)

實現了Comparable接口的類通過實現compareTo()方法從而確定該類對象的排序方式

完善第二個程序:

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Student implements Comparable{

private Integer sid;
private String sname;

public Student() {
}

public Student(Integer sid, String sname) {
this.sid = sid;
this.sname = sname;
}

public Integer getSid() {
return sid;
}

public void setSid(Integer sid) {
this.sid = sid;
}

public String getSname() {
return sname;
}

public void setSname(String sname) {
this.sname = sname;
}

@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + "]";
}

@Override
public int compareTo(Object o) {
/*把Object類強制轉為Student類型*/
Student stud = (Student) o;
/*當相等時返回0*/
if (this.sid == stud.sid){
return 0;
} else if (this.sid > stud.sid){/*當this大於obj時返回正數*/
return 1;
} else {/*當this小於obj時返回負數*/
return -1;
}
}

}

public class ArrayListTest {

public static void main(String[] args) {

/* 創建一個list集合 */
List students = new ArrayList();
/* 添加學生 */
students.add(new Student(1, "Lucy"));
students.add(new Student(1, "Krystal"));
students.add(new Student(2, "Amy"));
students.add(new Student(3, "Adam"));

/* 使用Collections.sort()方法來對集合進行排序 */
Collections.sort(students);
System.out.println(students);

}

}

程序輸出結果:
[Student [sid=1, sname=Lucy], Student [sid=1, sname=Krystal], Student [sid=2, sname=Amy], Student [sid=3, sname=Adam]]

按照我們自定義的排序標準排序成功

compareTo()方法和equals()的區別:

1:對於字符串而言,compareTo是按照字典順序比較兩個字符串,該比較基於字符串中各個字符的Unicode值,逐個往後比較,如果完全相同就返回0;如果當前字符比參數中對應位置的字符大,則返回正數,否則返回負數(其他類型的compareTo()比較請自行查閱)。

2:equals()是比較兩個對像是否相等,還比較他們的內存地址是否相等。

Reference: