Guava 21的Collect 新功能
一、简介
本文是关于 Google Guava 库第 21 版推出的新功能系列的第一篇。我们将讨论新添加的类以及与以前版本的 Guava 相比的一些主要变化。
更具体地说,我们将讨论common.collect包中的添加和更改。
Guava 21 在common.collect包中引入了一些新的有用的功能;让我们快速浏览一下其中的一些新实用程序以及如何充分利用它们。
2. 流
我们都对 Java 8 中最新添加的java.util.stream.Stream感到兴奋。好吧,Guava 现在很好地利用了流,并提供了 Oracle 可能错过的东西。
Streams是一个静态实用程序类,具有一些用于处理 Java 8 流的急需实用程序。
2.1. Streams.stream()
Streams类提供了四种使用Iterable、Iterator、Optional和Collection创建流的方法。
但是,不推荐使用Collection创建流,因为它是由 Java 8 开箱即用地提供的:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Stream<Integer> streamFromCollection = Streams.stream(numbers);
Stream<Integer> streamFromIterator = Streams.stream(numbers.iterator());
Stream<Integer> streamFromIterable = Streams.stream((Iterable<Integer>) numbers);
Stream<Integer> streamFromOptional = Streams.stream(Optional.of(1));
Streams类还提供了OptionalDouble、OptionalLong和OptionalInt的风格。这些方法返回一个仅包含该元素的流,否则为空流:
LongStream streamFromOptionalLong = Streams.stream(OptionalLong.of(1));
IntStream streamFromOptionalInt = Streams.stream(OptionalInt.of(1));
DoubleStream streamFromOptionalDouble = Streams.stream(OptionalDouble.of(1.0));
2.2. Streams.concat()
Streams类提供了连接多个同质流的方法。
Stream<Integer> concatenatedStreams = Streams.concat(streamFromCollection, streamFromIterable,streamFromIterator);
concat功能有几种形式—— LongStream、IntStream和DoubleStream。
2.3. Streams.findLast()
流有一个实用方法,可以使用*findLast()*方法查找流中的最后一个元素。
如果流中没有元素,此方法要么返回最后一个元素,要么返回Optional.empty() :
List<Integer> integers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Optional<Integer> lastItem = Streams.findLast(integers.stream());
findLast()方法适用于LongStream、IntStream和DoubleStream。
2.4. Streams.mapWithIndex()
通过使用*mapWithIndex()*方法,流的每个元素都携带有关它们各自位置(索引)的信息:
mapWithIndex( Stream.of("a", "b", "c"), (str, index) -> str + ":" + index)
这将返回Stream.of(“a:0″,”b:1″,”c:2”)。
使用重载的 mapWithIndex()也可以使用IntStream、LongStream和DoubleStream来实现。
2.5. Streams.zip()
为了使用某些函数映射两个流的对应元素,只需使用Streams 的 zip 方法:
Streams.zip(
Stream.of("candy", "chocolate", "bar"),
Stream.of("$1", "$2","$3"),
(arg1, arg2) -> arg1 + ":" + arg2
);
这将返回Stream.of(“candy:$1″,”chocolate:$2″,”bar:$3”);
结果流将仅与两个输入流中较短的一个一样长;如果一个流更长,它的额外元素将被忽略。
3. Comparator
Guava Ordering类已被弃用,并且在较新版本中处于删除阶段。JDK 8 中已经包含了Ordering类的大部分功能。
Guava 引入了Comparator以提供Java 8 标准库尚未提供的Ordering附加功能。
让我们快速浏览一下这些。
3.1. Comparator.isInOrder()
如果 Iterable 中的每个元素都大于或等于Comparator指定的前一个元素,则此方法返回 true :
List<Integer> integers = Arrays.asList(1,2,3,4,4,6,7,8,9,10);
boolean isInAscendingOrder = Comparators.isInOrder(
integers, new AscedingOrderComparator());
3.2. Comparator.isInStrictOrder()
非常类似于*isInOrder()*方法,但它严格地持有条件,元素不能等于前一个元素,它必须大于。前面的代码将为此方法返回 false。
3.3. Comparators.lexicographical()
此 API 返回一个新的Comparator实例——它按字典(字典)顺序排序,并成对比较相应的元素。在内部,它创建了一个*LexicographicalOrdering<S>()*的新实例。
4. MoreCollectors
MoreCollectors包含一些非常有用的Collectors,这些收集器在 Java 8 java.util.stream.Collectors中不存在,并且与com.google.common类型无关。
让我们来看看其中的一些。
4.1. MoreCollectors.toOptional()
在这里,Collector将包含零个或一个元素的流转换为Optional:
List<Integer> numbers = Arrays.asList(1);
Optional<Integer> number = numbers.stream()
.map(e -> e * 2)
.collect(MoreCollectors.toOptional());
如果流包含多个元素 - 收集器将抛出IllegalArgumentException。
4.2. MoreCollectors.onlyElement()
使用此 API,Collectors获取仅包含一个元素的流并返回该元素;如果流包含多个元素,则抛出IllegalArgumentException,或者如果流包含零元素,则抛出NoSuchElementException。
5. Interner.InternerBuilder
这是Guava 库中现有的内部构建器类。它提供了一些方便的方法来定义您喜欢的Interner的并发级别和类型(弱或强) :
Interners interners = Interners.newBuilder()
.concurrencyLevel(2)
.weak()
.build();