Java Core API提供了Comparable 和 Comparator 两个接口。根据名称来看我们做到它们能以某种方式比较东西。但是它们究竟有什么不同呢?下面的两个例子就会说明。这个简单的例子是比较两个高清电视的大小。当你读完本文,你就会做到如何使用Comparable 和 Comparator。

1. Comparable

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
class HDTV implements Comparable<HDTV> {
private int size;
private String brand;
public HDTV(int size, String brand) {
this.size = size;
this.brand = brand;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public int compareTo(HDTV tv) {
if (this.getSize() > tv.getSize())
return 1;
else if (this.getSize() < tv.getSize())
return -1;
else
return 0;
}
}
public class Main {
public static void main(String[] args) {
HDTV tv1 = new HDTV(55, "Samsung");
HDTV tv2 = new HDTV(60, "Sony");
if (tv1.compareTo(tv2) > 0) {
System.out.println(tv1.getBrand() + " is better.");
} else {
System.out.println(tv2.getBrand() + " is better.");
}
}
}
Sony is better.

Comparator

Comparator是让对象不同属性进行比较。例如:2个男人能比较的有”名字”或者”年龄”等等。(这样的情况使用comparable是不行的)

compare()是必须实现的。现在让我们用大小来比较这些电视。都使用大小来比较。最常见的Comparator使用是排序。集合和数组类都提供了使用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
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class HDTV {
private int size;
private String brand;
public HDTV(int size, String brand) {
this.size = size;
this.brand = brand;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
class SizeComparator implements Comparator<HDTV> {
@Override
public int compare(HDTV tv1, HDTV tv2) {
int tv1Size = tv1.getSize();
int tv2Size = tv2.getSize();
if (tv1Size > tv2Size) {
return 1;
} else if (tv1Size < tv2Size) {
return -1;
} else {
return 0;
}
}
}
public class Main {
public static void main(String[] args) {
HDTV tv1 = new HDTV(55, "Samsung");
HDTV tv2 = new HDTV(60, "Sony");
HDTV tv3 = new HDTV(42, "Panasonic");
ArrayList<HDTV> al = new ArrayList<HDTV>();
al.add(tv1);
al.add(tv2);
al.add(tv3);
Collections.sort(al, new SizeComparator());
for (HDTV a : al) {
System.out.println(a.getBrand());
}
}
}

输出:

Panasonic
Samsung
Sony

通常我们可以使用 Collections.reverseOrder()来获得降序数组。如下:

1
2
3
4
5
6
7
8
9
10
11
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(3);
al.add(1);
al.add(2);
System.out.println(al);
Collections.sort(al);
System.out.println(al);
Comparator<Integer> comparator = Collections.reverseOrder();
Collections.sort(al,comparator);
System.out.println(al);

输出:

[3,1,2]
[1,2,3]
[3,2,1]

3. 什么时候该用哪个?

简言之,用于实现可比用Comparable,这意味着它的实例可以彼此进行比较。

一个类实现Comparator 将是比较其他类。1)它可以用于传递到方法中进行排序,如Collections.sort()或Arrays.sort()中,为了精确地控制排序顺序。2)也可以用于控制某些数据结构的顺序,如作为排序的集或排序的映射。

例如,要创建一个TreeSet中。我们可以通过构造一个Comparator或使对象可以比较。

方法1 - TreeSet的(Comparator比较)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Dog {
int size;
Dog(int s) {
size = s;
}
}
class SizeComparator implements Comparator<Dog> {
@Override
public int compare(Dog d1, Dog d2) {
return d1.size - d2.size;
}
}
public class ImpComparable {
public static void main(String[] args) {
TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // pass comparator
d.add(new Dog(1));
d.add(new Dog(2));
d.add(new Dog(1));
}
}

方法2 实现Comparable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Dog implements Comparable<Dog>{
int size;
Dog(int s) {
size = s;
}
@Override
public int compareTo(Dog o) {
return o.size - this.size;
}
}
public class ImpComparable {
public static void main(String[] args) {
TreeSet<Dog> d = new TreeSet<Dog>();
d.add(new Dog(1));
d.add(new Dog(2));
d.add(new Dog(1));
}
}

参考文档