Java比较器

本文最后更新于:6 天前

Java实现对象排序的方式有两种,涉及到两个接口

  • 自然排序:java.lang.Comparable
  • 定制排序:java.util.Comparator

自然排序的实现思路类似于C++的仿函数,当需要对自定义类的对象集合排序时,可以采用自然排序Comparable接口。

定制排序是对已经实现自然排序的类且想按照新的任意规则排序时,在排序时传入Comparator接口对象,从而实现。

PS: Java的类库思路真的好整齐。

Comparable接口

实现Comparable接口,重写compareTo()方法。思路及方法与C++仿函数类似。

注意,并不强求重写hashCode与equals方法,但对于某些数据结构(TreeSet等),为了保证排序结果与内部排序结果的一致性,通常选择重写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person
implements Comparable<Person>
{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}

@Override
public int compareTo(Person o) {
if(this.age != o.age)
return this.age - o.age;

return this.name.compareTo(o.name);
}
}

Comparator接口

当元素类型没有实现Comparable接口而又不方便修改代码,或者实现了Comparable接口但是排序规则需要暂时修改时,使用Comparator接口,并重写compare方法。


Arrays.sort()方法,可以直接传入对象数组,此时按照自然排序即comparable接口提供的方法去从小到大排序;也可以传入实现了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
import java.util.Arrays;
import java.util.Comparator;

public class Test {
public static void main(String[] args) {
Person[] persons = new Person[4];
persons[0] = new Person("Mary", 18);
persons[1] = new Person("Mike", 19);
persons[2] = new Person("Lucy", 17);
persons[3] = new Person("Q", 18);
Arrays.sort(persons);
System.out.println(Arrays.toString(persons));

Arrays.sort(persons, new Comparator<Person>(){
@Override
public int compare(Person p1, Person p2){
if(p1.getAge() != p2.getAge())
return -(p1.getAge() - p2.getAge());
return -p1.getName().compareTo(p2.getName());
}
});
System.out.println(Arrays.toString(persons));
}
}

class Person
implements Comparable<Person>
{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}

@Override
public int compareTo(Person o) {
if(this.age != o.age)
return this.age - o.age;

return this.name.compareTo(o.name);
}

@Override
public String toString(){
return this.name + " " + this.age;
}

public String getName(){
return name;
}

public int getAge(){
return age;
}

}

通过Comparable接口,实现了从小到大排序;通过匿名类实现了Comparator接口排序。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!