Ordering是Guava基于比较器[Comparator]的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。从实现上说,Ordering实例就是一个特殊的Comparator实例。Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。
Ordering比较器构造方法:
S.N. | 方法及说明 |
---|---|
1 | static Ordering<Object> allEqual() 返回一个所有对象都相等的排序器,这个排序器不会对元素顺序产生影响 |
2 | static Ordering<Object> arbitrary() 返回一个任意顺序的排序器,元素的顺序不定 |
3 | static <T> Ordering<T> compound(Iterable<? extends Comparator<? super T>> comparators) 复合多个排序器,排序规则按照排序器顺序决定,第一排序规则相等,则使用第二排序规则,以此类推 |
4 | static <T> Ordering<T> from(Comparator<T> comparator) 由comparator构造Ordering排序器 |
5 | static <C extends Comparable> Ordering<C> natural() 返回自然顺序排序器,即从小到大排序 |
6 | static Ordering<Object> usingToString() 按对象的字符串形式做字典排序 |
常用方法说明:
S.N. | 方法及说明 |
---|---|
1 | <U extends T> Ordering<U> compound(Comparator<? super U> secondaryComparator) 合并排序器 |
2 | <E extends T> List<E> greatestOf(Iterable<E> iterable, int k) <E extends T> List<E> greatestOf(Iterator<E> iterator, int k) 返回TOP K |
3 | <E extends T> List<E> leastOf(Iterable<E> iterable, int k) <E extends T> List<E> leastOf(Iterator<E> elements, int k) 返回最小的TOP K |
4 | boolean isOrdered(Iterable<? extends T> iterable) 判断列表是否有序 |
5 | <E extends T> E max(E a, E b) <E extends T> E max(E a, E b, E c, E… rest) <E extends T> E max(Iterable<E> iterable) <E extends T> E max(Iterator<E> iterator) 返回最大值 |
6 | <E extends T> E min(E a, E b) <E extends T> E min(E a, E b, E c, E… rest) <E extends T> E min(Iterable<E> iterable) <E extends T> E min(Iterator<E> iterator) 返回最小值 |
7 | <S extends T> Ordering<S> nullsFirst() 使用当前排序器,但额外把null值排到最前面 |
8 | <S extends T> Ordering<S> nullsLast() 使用当前排序器,但额外把null值排到最后面 |
9 | <F> Ordering<F> onResultOf(Function<F,? extends T> function) 对集合中元素调用Function,再按返回值用当前排序器排序 |
10 | <S extends T> Ordering<S> reverse() 返回相反顺序 |
11 | <E extends T> List<E> sortedCopy(Iterable<E> elements) 返回一个排序后的列表,并且不改变排序列表顺序 |
示例代码:
Person实体类:
class Person {
String name;
Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
按照name自然排序构建Ordering排序器:
/*根据name自然排序构建Ordering*/
Ordering<Person> nameOrdering = Ordering.natural().nullsFirst().onResultOf(new Function<Person, String>(){
public String apply(Person person) {
return person.name;
}
});
使用sortedCopy对列表进行排序,并且生成新的已排序的列表(不影响原列表的顺序):
List<Person> nameOrderedList = nameOrdering.sortedCopy(personList);
使用greatestOf、leastOf获取Top K:
/*greatestOf抽取Top K*/
System.out.println("Top K by Name:" + nameOrdering.greatestOf(personList, 2));
/*leastOf抽取最小的Top K*/
System.out.println("least Top K by Name:" + nameOrdering.leastOf(personList, 2));
/*也可以使用迭代器抽取Top K*/
System.out.println("Top K by Name:" + nameOrdering.greatestOf(personList.iterator(), 2));
System.out.println("least Top K by Name:" + nameOrdering.leastOf(personList.iterator(), 2));
按照age自然顺序排序构建Ordering排序器:
/*根据age自然排序构建Ordering*/
Ordering<Person> ageOrdering = Ordering.natural().nullsFirst().onResultOf(new Function<Person, Integer>(){
public Integer apply(Person person) {
return person.age;
}
});
personList.sort(ageOrdering);
使用reverse()获取逆序列表:
/*使用reverse()获取逆序ordering*/
personList.sort(ageOrdering.reverse());
System.out.println("age Reverse Order:" + personList);
compound构造复合排序ordering,先按照name排序,name相同则按照age排序:
Ordering<Person> compoundOrdering = nameOrdering.compound(ageOrdering);
personList.add(new Person("Michael", 25));
personList.sort(compoundOrdering);
System.out.println("compoundOrdering:" + personList);
对列表进行排序,可以使用Collections.sort(list, comparator)或者list.sort(comparator),排序后都会对原序列的顺序产生影响,Java8之后建议使用list.sort。但是有时候存在这样的场景,希望得到一个有序序列,但是不希望原序列的顺序发生改变,这时候可以使用Guava提供的Ordering排序器,通过sortedCopy方法返回一个有序序列。
测试代码:码云 – 卓立 – Guava测试