排序器Ordering
是Guava
流畅风格比较器Comparator
的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。
参考资料
概述
排序器Ordering
是Guava
流畅风格比较器Comparator
的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。
从实现上说,Ordering
实例就是一个特殊的Comparator
实例。Ordering
把很多基于Comparator
的静态方法(如Collections.max
)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。
使用
创建方式
对可排序类型做自然排序,如数字按大小,日期按先后排序
Ordering.natural()
1 | List<Integer> list = Arrays.asList(1, 5, 3, 8, 2); |
按对象的字符串形式做字典排序
Ordering.usingToString
1 | List<String> listString = Lists.newArrayList("wang", "test", "a"); |
使预先存在的比较器进行排序
Ordering.from(Comparator)
1 | List<Worker> workers = Lists.newArrayList(worker, worker2, worker22, worker3); |
链式调用方法:通过链式调用,可以由给定的排序器衍生出其它排序器
reverse
获取语义相反的排序器
@Test
public void testOrderReverse() {
List
Collections.sort(list, Ordering.natural().reverse());
log.info(“获取最大的元素” + Ordering.natural().max(list).toString());
log.info(“排序后” + list.toString());
}
1
2
3
4
5
6
7
nullsFirst nullsLast
使用当前排序器,但额外把null值排到最前面,最后,原生的JDKCollections.sort会出现异常的,如果排序元素为空
原生调用
/**
* 排序中出现,空指针会异常的!
/
@Test(expected = NullPointerException.class)
public void testJDKOrderIssue() {
List
log.info(“排序前” + list.toString());
Collections.sort(list); // 出现异常…
}
1
2
3
4
5
6
7
8
9
使用Guava Ordering
/*
- 将空值放置在最前面的情况
- /
@Test
public void testOrderNaturalByNullFirst() {
Listlist = Arrays.asList(1, 5, null, 3, 8, 2);
Collections.sort(list, Ordering.natural().nullsFirst());
log.info(“空在最前面-排序后” + list.toString());
}
1
2
3
4
5
6
7
8
9
多字段排序 compound(Comparator)
合成另一个比较器,以处理当前排序器中的相等情况。
public class WorkerIdComparator implements Comparator
@Override
public int compare(Worker worker1, Worker worker2) {
return Ints.compare(worker1.getWorkId(), worker2.getWorkId());
}
}
public class WorkerNameComparator implements Comparator
@Override
public int compare(Worker worker1, Worker worker2) {
return worker1.getName().compareTo(worker2.getName());
}
}
/**
guava 多参数排序
Ordering.from 的使用
/
@Test
public void testFrom() {
Worker worker = new Worker(1, “wangji”);
Worker worker2 = new Worker(11, “guava”);
Worker worker22 = new Worker(11, “aaa”);
Worker worker3 = new Worker(111, “wangji3”);
Listworkers = Lists.newArrayList(worker, worker2, worker22, worker3);
OrderingorderWorker = Ordering.from(new WorkerIdComparator());
Collections.sort(workers, orderWorker);
log.info(“单参数:” + workers.toString());// compound 相等的情况下,考虑第二个参数进行比较
OrderingorderManyWorker = Ordering.from(new WorkerIdComparator()).compound(new WorkerNameComparator()).reverse();
Collections.sort(workers, orderManyWorker);
log.info(“多参数:” + workers.toString());
}
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
运用排序器:Guava的排序器实现有若干操纵集合或元素值的方法
isOrdered
判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
/**
- isOrdered(Iterable) 判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
- /
@Test
public void testOrderNatural() {
Listlist = Arrays.asList(1, 5, 3, 8, 2);
Collections.sort(list);
boolean order = Ordering.natural().isOrdered(list); //是否为按照这样的顺序排好序的!自然的排序
log.info(“排好序的:” + (order == true ? “是的” : “不是”));
}
1
2
3
4
5
6
7
8
9
10
min(E, E),min(E, E, E, E…),min(Iterable)
返回两个参数中最小的那个。如果相等,则返回第一个参数。
返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数
返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException。
max同理,这样的操作节省了一点时间和精力
/**
返回元素中的最大的值,同理最小的
/
@Test
public void testMax() {
Listlist = Arrays.asList(1, 5, 3, 8, 2);
log.info(“获取最大的元素” + Ordering.natural().max(list).toString()); //获取最大的元素8log.info(“获取最大的元素” + Ordering.natural().reverse().max(list).toString());//获取最大的元素1
}
1
2
3
4
5
6
7
8
9
10
greatestOf
获取可迭代对象中最大的k个元素,简化我们的操作的工作量
/**
返回一个排序对象中的最大的多少个元素-是不稳定的。
/
@Test
public void testGreaTestOf() {
Listlist = Arrays.asList(1, 5, 3, 8, 2);
ListlistMaxtOfK = Ordering.natural().greatestOf(list, 3);//获取可迭代对象中最大的k个元素。
log.info(“获取最大的k个元素:” + listMaxtOfK.toString());List
listMaxtOfMinik = Ordering.natural().reverse().greatestOf(list, 3);
// listMaxtOfK.add(1); UnmodifiableCollection 返回的是不可变对象,不可以进行操作
log.info(“获取最大的Minik个元素:” + listMaxtOfMinik.toString());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
sortedCopy(Iterable) immutableSortedCopy(Iterable)
复制排序后的元素的副本,不过这里不是深复制,需要保证集合元素中的不可变性,返回可变的集合元素和不可变的集合元素
/**
复制一个副本,这里没有进行集合元素的深复制,需要保证集合对象中为不可变对象
这里可以通过sortedCopy,返回一个可变的对象,immutableSortedCopy返回一个不可变的对象
/
@Test
public void testSortedCopy() {
Listlist = Arrays.asList(1, 5, 3, 8, 2);
ListduplicateList = Ordering.natural().sortedCopy(list);// 返回一个副本
if (!Objects.equals(list, duplicateList)) {log.info("返回的一个副本" + duplicateList.toString()); duplicateList.add(10); log.info("返回的一个可变的副本" + duplicateList.toString());
}
ListduplicateImmutableList = Ordering.natural().immutableSortedCopy(list); // 返回一个不可变的副本
if (!Objects.equals(list, duplicateImmutableList)) {log.info("返回的一个副本" + duplicateImmutableList.toString()); try { duplicateImmutableList.add(10); } catch (Exception e) { log.info("返回的一个可变的副本不能添加"); }
}
}