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接口排序。