简介
排序器 Ordering
是 Guava流畅风格比较器 Comparator
的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。
从实现上说,Ordering 实例就是一个特殊的 Comparator 实例。Ordering 把很多基于 Comparator 的静态方法(如 Collections.max
)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。
类方法说明
官方文档:Source code
方法名称 | 方法描述 |
---|---|
allEqual() |
返回一个Ordering,所有值的排序地位都是平等的,表明无排序。 将此排序传递给任何稳定排序算法都不会导致元素顺序发生变化。 |
arbitrary() |
返回所有对象的任意顺序,即compare(a, b) == 0 就是 a == b (identity equality)。 本身的排序是没有任何含义,但是在VM的生命周期是一个常量。 |
binarySearch(List<? extends T> sortedList, T key) |
已过时,请使用 Collections.binarySearch(List, Object, Comparator) . |
compare(T left, T right) |
比较两个参数的顺序。 |
compound(Comparator<? super U> secondaryComparator) |
返回一个Ordering,传入比较器作为第二排序元素。 |
compound(Iterable<? extends Comparator<? super T>> comparators) |
返回一个Ordering,会根据传入比较器集合一次比较,直到找到一个非零的结果。 |
explicit(List<T> valuesInOrder) |
返回一个Ordering,根据他们出现在给定的列表的顺序比较对象 |
explicit(T leastValue, T... remainingValuesInOrder) |
返回一个Ordering,比较对象根据它们的传入的顺序。 |
from(Comparator<T> comparator) |
返回一个传入comparator实例的Ordering。 |
from(Ordering<T> ordering) |
已过时。 不需要使用它 |
greatestOf(Iterable<E> iterable, int k) |
根据Ordering对传入iterable由大到小排序,返回前K位的集合。 |
greatestOf(Iterator<E> iterator, int k) |
根据Ordering对传入iterable由大到小排序,返回前K位的集合。 |
immutableSortedCopy(Iterable<E> elements) |
返回一个不可变的集合,包含根据Ordering对传入元素排序后的所有元素。 |
isOrdered(Iterable<? extends T> iterable) |
根据Ordering对传入iterable元素迭代,如果下一个元素大于或等于上一个元素,返回true。 |
isStrictlyOrdered(Iterable<? extends T> iterable) |
根据Ordering对传入iterable元素迭代,如果下一个元素严格大于上一个元素,返回true。 |
leastOf(Iterable<E> iterable, int k) |
根据Ordering对传入iterable由小到大排序,返回前K位的集合。 |
leastOf(Iterator<E> iterator, int k) |
根据Ordering对传入iterable由小到大排序,返回前K位的集合。 |
lexicographical() |
返回一个新的Ordering,通过相应的元素两两迭代,直到找到一个非零的结果。强加"字典顺序"。 |
max(E a, E b) |
根据Ordering返回传入参数的最大值。 |
max(E a, E b, E c, E... rest) |
根据Ordering返回传入参数的最大值。 |
max(Iterable<E> iterable) |
根据Ordering返回传入参数的最大值。 |
max(Iterator<E> iterator) |
根据Ordering返回传入参数的最大值。 |
min(E a, E b) |
根据Ordering返回传入参数的最小值。 |
min(E a, E b, E c, E... rest) |
根据Ordering返回传入参数的最小值。 |
min(Iterable<E> iterable) |
根据Ordering返回传入参数的最小值。 |
min(Iterator<E> iterator) |
根据Ordering返回传入参数的最小值。 |
natural() |
对可排序类型做自然排序,如数字按大小,日期按先后排序 |
nullsFirst() |
根据Ordering排序,null值放在最前面,并使用它来比较非空值。 |
nullsLast() |
根据Ordering排序,null值放在最后面,并使用此排序来比较非空值。 |
onResultOf(Function<F,? extends T> function) |
将传入function应用到每个元素上面,再通过Ordering进行排序。 |
<S extends T>Ordering<S> |
reverse() 返回与当前Ordering相反的排序。相当于 Collections.reverseOrder(Comparator) 。 |
<E extends T> List<E> |
sortedCopy(Iterable<E> elements) 返回一个可变的集合,包含根据Ordering对传入元素排序后的所有元素。 |
usingToString() |
根据toString返回的字符串按照字典顺序排序。 |
使用Demo
java
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Doubles;
import junit.framework.TestCase;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.*;
import static java.util.Arrays.asList;
/**
* 排序
*/
public class OrderingTests extends TestCase {
/**
* 1、allEqual 允许有null
*/
public void testAllEqual() {
Ordering<Object> comparator = Ordering.allEqual();
System.out.println(comparator.equals(comparator.reverse()));
assertEquals(0, comparator.compare(null, null));
assertEquals(0, comparator.compare(new Object(), new Object()));
assertEquals(0, comparator.compare("apples", "oranges"));
assertEquals("Ordering.allEqual()", comparator.toString());
List<String> strings = ImmutableList.of("b", "a", "d", "c");
List<String> sortedCopy = comparator.sortedCopy(strings);
assertEquals(strings, sortedCopy);
ImmutableList<String> immutableSortedCopy = comparator.immutableSortedCopy(strings);
assertEquals(strings, immutableSortedCopy);
}
/**
* 2、natural 不能有null
*/
public void testNatural() {
Ordering<Integer> comparator = Ordering.natural();
try {
comparator.compare(1, null);
fail();
} catch (NullPointerException expected) {
}
try {
comparator.compare(null, 2);
fail();
} catch (NullPointerException expected) {
}
try {
comparator.compare(null, null);
fail();
} catch (NullPointerException expected) {
}
assertEquals("Ordering.natural()", comparator.toString());
}
/**
* 3、List集合 复杂排序示例
*/
public void testComplicatedOrderingExample() {
Ordering<Iterable<Integer>> example = Ordering.<Integer>natural().nullsFirst().reverse().lexicographical().reverse().nullsLast();
List<Integer> list1 = Lists.newArrayList();
List<Integer> list2 = Lists.newArrayList(1);
List<Integer> list3 = Lists.newArrayList(1, 1);
List<Integer> list4 = Lists.newArrayList(1, 2);
List<Integer> list5 = Lists.newArrayList(1, null, 2);
List<Integer> list6 = Lists.newArrayList(2);
Integer nullInt = null;
List<Integer> list7 = Lists.newArrayList(nullInt);
List<Integer> list8 = Lists.newArrayList(nullInt, nullInt);
List<List<Integer>> list = Lists.newArrayList(list1, list2, list3, list4, list5, list6, list7, list8, null);
List<List<Integer>> sorted = example.sortedCopy(list);
/**
* [null, null]
* [null]
* [1, null, 2]
* [1, 1]
* [1, 2]
* [1]
* [2]
* []
* null
*/
sorted.forEach(System.out::println);
}
/**
* 4、from 把给定的 Comparator 转化为排序器
*/
public void testFrom() {
// String.CASE_INSENSITIVE_ORDER 按照 ASCII 排序
Ordering<String> caseInsensitiveOrdering = Ordering.from(String.CASE_INSENSITIVE_ORDER);
assertTrue(caseInsensitiveOrdering.compare("A", "a") == 0);
assertTrue(caseInsensitiveOrdering.compare("a", "B") < 0);
assertTrue(caseInsensitiveOrdering.compare("B", "a") > 0);
ArrayList<String> list = Lists.newArrayList("dehua", "abcdef", "ABCDEF", "rapido", "lbsse","lasse");
List<String> sortedCopy = caseInsensitiveOrdering.sortedCopy(list);
sortedCopy.forEach(System.out::println);
}
/*
* 5、explicit(ExplicitOrdering)返回一个Ordering,根据它们的传入的顺序比较对象。只能比较参数列表中存在的对象
*/
public void testExplicit_none() {
Comparator<Integer> c = Ordering.explicit(Collections.emptyList());
try {
c.compare(0, 0);
} catch (Exception e) {
// e.printStackTrace();
}
assertEquals("Ordering.explicit([])", c.toString());
}
public void testExplicit_one() {
Comparator<Integer> c = Ordering.explicit(0);
assertEquals(0, c.compare(0, 0));
try {
c.compare(0, 1);
fail();
} catch (Exception e) {
// e.printStackTrace();
}
assertEquals("Ordering.explicit([0])", c.toString());
}
public void testExplicit_two() {
// Comparator<Integer> c = Ordering.explicit(42, 5);
// assertEquals(0, c.compare(5, 5));
// assertTrue(c.compare(5, 42) > 0);
// assertTrue(c.compare(42, 5) < 0);
Comparator<Integer> c = Ordering.explicit(5, 10);
assertEquals(0, c.compare(5, 5));
assertTrue(c.compare(5, 10) < 0);
assertTrue(c.compare(10, 5) > 0);
try {
c.compare(5, 9);
fail();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void testExplicit_three() {
// explicit:根据传入对象的顺序排序
Double first = 0.2;
Double[] second = {0.1, 0.3, 0.5};
List<Double> numbers = Lists.asList(first, second);
//排序比较器:根据原始的大小排序
Ordering<Double> peopleOrdering = new Ordering<Double>() {
@Override
public int compare(Double left, Double right) {
return Doubles.compare(left, right);
}
};
peopleOrdering.reverse().explicit(numbers).sortedCopy(numbers).forEach(System.out::println);//[ 0.2,0.1, 0.3, 0.5]
}
public void testExplicit_sortingExample() {
Comparator<Integer> c = Ordering.explicit(2, 8, 6, 1, 7, 5, 3, 4, 0, 9);
List<Integer> list = Arrays.asList(0, 3, 5, 6, 7, 8, 9);
Collections.sort(list, c);
// 8, 6, 7, 5, 3, 0, 9
list.forEach(System.out::println);
}
/**
* key重复异常
*/
public void testExplicit_withDuplicates() {
try {
Ordering.explicit(1, 2, 3, 4, 2);
fail();
} catch (IllegalArgumentException expected) {
expected.printStackTrace();
}
}
/**
* 6、arbitrary 返回所有对象的任意顺序
*/
public void testArbitrary_withoutCollisions() {
List<Integer> list = Lists.newArrayList();
for (int i = 0; i < 50; i++) {
list.add(i);
}
Ordering<Object> arbitrary = Ordering.arbitrary();
Collections.sort(list, arbitrary);
list.forEach(System.out::println);
assertEquals("Ordering.arbitrary()", arbitrary.toString());
}
/**
* 7、usingToString
* 按对象的字符串形式做字典排序 [lexicographical ordering]
*/
public void testUsingToString() {
Ordering<Object> ordering = Ordering.usingToString();
assertEquals("Ordering.usingToString()", ordering.toString());
List<String> list = Lists.newArrayList("lasse", "jerry", "harry", "eva", "jhon", "neron");
System.out.println("list:" + list);
// 使用Comparable类型的自然顺序, 例如:整数从小到大,字符串是按字典顺序;
Ordering<String> naturalOrdering = Ordering.natural();
// 使用toString()返回的字符串按字典顺序进行排序;
Ordering<Object> usingToStringOrdering = Ordering.usingToString();
// 返回一个所有对象的任意顺序
Ordering<Object> arbitraryOrdering = Ordering.arbitrary();
System.out.println("naturalOrdering:" + naturalOrdering.sortedCopy(list));
System.out.println("usingToStringOrdering:" + usingToStringOrdering.sortedCopy(list));
System.out.println("arbitraryOrdering:" + arbitraryOrdering.sortedCopy(list));
}
/**
* 8、reverse 取返
*/
public void testReverse() {
List<String> list = Lists.newArrayList("lasse", "jerry", "harry", "eva", "jhon", "neron");
Collections.sort(list, Ordering.natural().reverse());
list.forEach(System.out::println);
}
private enum StringLengthFunction implements Function<String, Integer> {
StringLength;
@Override
public Integer apply(String string) {
return string.length();
}
}
/**
* 9、onResultOf 将传入function应用到每个元素上面,再通过Ordering进行排序。
*/
public void testOnResultOf_1() {
// 外部枚举函数
Ordering<String> ordering = Ordering.natural().onResultOf(StringLengthFunction.StringLength);
assertTrue(ordering.compare("to", "be") == 0);
assertTrue(ordering.compare("or", "not") < 0);
assertTrue(ordering.compare("that", "to") > 0);
assertEquals("Ordering.natural().onResultOf(StringLength)", ordering.toString());
ArrayList<String> list = Lists.newArrayList("lasse", "abcds", "ABCDEF", "rapido", "chengxumiao");
ordering.sortedCopy(list).forEach(System.out::println);
}
public void testOnResultOf_2() {
// 匿名内部类函数
Ordering<String> ordering = Ordering.natural().onResultOf(new Function<String, Comparable>() {
@Override
public Comparable apply(@Nullable String input) {
return input.length();
}
});
ArrayList<String> list = Lists.newArrayList("lasse", "abcds", "ABCDEF", "rapido", "chengxumiao");
ordering.sortedCopy(list).forEach(System.out::println);
}
public void testOnResultOf_3() {
// lambda 表达式函数
Ordering<String> ordering = Ordering.natural().reverse().onResultOf(str -> str.length());
ArrayList<String> list = Lists.newArrayList("lasse", "abcds", "ABCDEF", "rapido", "chengxumiao");
ordering.sortedCopy(list).forEach(System.out::println);
}
/**
* 10、nullsFirst
*/
public void testNullsFirst_NullsLast() {
ArrayList<String> list = Lists.newArrayList("lasse", null, "abcds", "ABCDEF", null, "rapido", "chengxumiao");
Collections.sort(list, Ordering.natural().nullsFirst());
list.forEach(System.out::println);
Ordering.natural().nullsLast().sortedCopy(list).forEach(System.out::println);
}
/**
* 11、NullsLast
*/
public void testNullsLast() {
ArrayList<String> list = Lists.newArrayList("tingfeng", null, "abcds", "ABCDEF", null, "rapido", "chengxumiao");
Ordering.natural().nullsLast().sortedCopy(list).forEach(System.out::println);
}
/**
* 12、isOrdered 下一个元素大于或等于上一个元素,返回true
*/
public void testIsOrdered() {
Ordering<Comparable> ordering = Ordering.natural();
assertFalse(ordering.isOrdered(asList(5, 3, 0, 9)));
assertFalse(ordering.isOrdered(asList(0, 5, 3, 9)));
assertTrue(ordering.isOrdered(asList(0, 3, 5, 9)));
assertTrue(ordering.isOrdered(asList(0, 0, 3, 3)));
assertTrue(ordering.isOrdered(asList(0, 3)));
assertTrue(ordering.isOrdered(Collections.singleton(1)));
assertTrue(ordering.isOrdered(Collections.<Integer>emptyList()));
}
/**
* 13、isStrictlyOrdered 下一个元素大于上一个元素,返回true
*/
public void testIsStrictlyOrdered() {
Ordering<Comparable> ordering = Ordering.natural();
assertFalse(ordering.isStrictlyOrdered(asList(5, 3, 0, 9)));
assertFalse(ordering.isStrictlyOrdered(asList(0, 5, 3, 9)));
assertFalse(ordering.isStrictlyOrdered(asList(0, 0, 3, 3)));
assertTrue(ordering.isStrictlyOrdered(asList(0, 3, 5, 9)));
assertTrue(ordering.isStrictlyOrdered(asList(0, 3)));
assertTrue(ordering.isStrictlyOrdered(Collections.singleton(1)));
assertTrue(ordering.isStrictlyOrdered(Collections.<Integer>emptyList()));
}
/**
* 判断集合是否只读
*/
private static void assertListImmutable(List<Integer> result) {
try {
result.set(0, 1);
fail();
} catch (UnsupportedOperationException expected) {
// pass
}
}
/**
* 14、leastOf 有点类似截取集合前几位的概念
*/
public void testLeastOfIterable_simple_1() {
List<Integer> result = Ordering.natural().leastOf(Arrays.asList(3, 4, 5, -1), 2);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.of(-1, 3), result);
}
public void testLeastOfIterator_simple_1() {
List<Integer> result = Ordering.natural().leastOf(Iterators.forArray(3, 4, 5, -1), 2);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.of(-1, 3), result);
}
public void testLeastOfIterable_simple_nMinusOne_withNullElement() {
List<Integer> list = Arrays.asList(3, null, 5, -1);
List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size() - 1);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.of(-1, 3, 5), result);
}
/**
* 15、min 和 max
*/
public void testIteratorMinAndMax() {
Ordering<Comparable> ordering = Ordering.natural();
List<Integer> ints = Lists.newArrayList(5, 3, 0, 9);
assertEquals(9, (int) ordering.max(ints));
assertEquals(0, (int) ordering.min(ints));
assertEquals(9, (int) ordering.max(ints.iterator()));
assertEquals(0, (int) ordering.min(ints.iterator()));
assertEquals(9, (int) ordering.max(ints.listIterator()));
assertEquals(0, (int) ordering.min(ints.listIterator()));
// 当值相同时,返回第一个参数,此处a正确,b就不正确
Integer a = new Integer(4);
Integer b = new Integer(4);
ints = Lists.newArrayList(a, b, b);
assertSame(a, ordering.max(ints.iterator()));
assertSame(a, ordering.min(ints.iterator()));
}
public void testIteratorMinExhaustsIterator() {
List<Integer> ints = Lists.newArrayList(9, 0, 3, 5);
Iterator<Integer> iterator = ints.iterator();
assertEquals(0, (int) Ordering.natural().min(iterator));
assertFalse(iterator.hasNext());
}
public void testIteratorMaxExhaustsIterator() {
List<Integer> ints = Lists.newArrayList(9, 0, 3, 5);
Iterator<Integer> iterator = ints.iterator();
assertEquals(9, (int) Ordering.natural().max(iterator));
assertFalse(iterator.hasNext());
}
}