Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Comparable 接口

该接口只包含一个方法,x.compareTo(y)。实现Comparable接口的类的对象可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器就可以支持排序。

该方法通过返回负数、0、正数,来表示输入的对象小于,等于,大于调用该方法的对象。x.compareTo(y)==0,说明x与y相等。 x.compareTo(y) < 0,说明x<y;

Comparator接口

该接口包含compare(x,y)方法。若需要控制某个类的次序,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。

实践

若一个类实现了Comparable接口,就意味着“该类支持排序”。在调用sorts方法的时候就不需要在指定比较器(Comparator)。

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package javatest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
* @description:
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-26 23:24:59
* @version: 0.0.1
*/
public class JavaComparableComparator {

public static void main(String[] args) {
List<House> houses = new ArrayList<>();
// 报错:No enclosing instance of type JavaComparableComparator is accessible.
// 原因、解决:
// 内部类是动态的(无static关键字修饰),而main方法是静态的,
// 普通的内部类对象隐含地保存了一个引用,指向创建它的外围类对象,
// 所以要在static方法(类加载时已经初始化)调用内部类的必须先创建外部类。
House h1 = new JavaComparableComparator().new House(95);
House h2 = new JavaComparableComparator().new House(110);
House h3 = new JavaComparableComparator().new House(80);
House h4 = new JavaComparableComparator().new House(150);
houses.add(h1);
houses.add(h2);
houses.add(h3);
houses.add(h4);

// Comparator常见使用
System.out.println("before sort");
houses.forEach((n)-> System.out.print(n.price + " "));
houses.sort(new JavaComparableComparator().new HouseComparator());
System.out.println("\nafter sort");
houses.forEach((n)-> System.out.print(n.price + " "));

// Collections.sort(houses) , 不指定Comparator会报错
Collections.sort(houses,new JavaComparableComparator().new HouseComparator());

// =======================================================================
// Comparable常见使用
List<HouseComparable> housesComparables = new ArrayList<>();
HouseComparable hc1 = new JavaComparableComparator().new HouseComparable(95);
HouseComparable hc2 = new JavaComparableComparator().new HouseComparable(110);
HouseComparable hc3 = new JavaComparableComparator().new HouseComparable(80);
HouseComparable hc4 = new JavaComparableComparator().new HouseComparable(150);
housesComparables.add(hc1);
housesComparables.add(hc2);
housesComparables.add(hc3);
housesComparables.add(hc4);

System.out.println("\n\n\n\nbefore sort");
housesComparables.forEach((n)-> System.out.print(n.price + " "));
// 无需指定 Comparator,他自己就是可以进行比较的类
//Collections sort
Collections.sort(housesComparables);

System.out.println("\nafter sort");
housesComparables.forEach((n)-> System.out.print(n.price + " "));


}

/**
*普通House
*/
class House {
int price;
public House(int price) {
this.price = price;
}
}
/**
* House比较器
*/
class HouseComparator implements Comparator<House> {
@Override
public int compare(House o1, House o2) {
if (o1.price > o2.price) {
return 1;
} else if (o1.price < o2.price) {
return -1;
}
return 0;
}

}

/**
* 可排序的House
*/
class HouseComparable implements Comparable<HouseComparable> {
int price;

public HouseComparable(int price) {
this.price = price;
}

@Override
public int compareTo(HouseComparable o) {

if (price < o.price) {
return -1;
} else if (price > o.price) {
return 1;
}

return 0;
}

}

}

Collections调用重写的compareTo

Collections如何调用重写的compareTo方法的

1
2
Collections.sort(List<T> list); 
Collections.sort(List<T> list, Comparator<? super T> c)

如果待排序的列表中是数字或者字符,可以直接使用Collections.sort(list);当需要排序的集合或数组不是单纯的数字型时,需要自己定义排序规则,实现一个Comparator比较器。

参考:

详解Java中Comparable和Comparator接口的区别

评论