Contents

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类提供了四种使用IterableIteratorOptionalCollection创建流的方法。

但是,不推荐使用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类还提供了OptionalDoubleOptionalLongOptionalInt的风格。这些方法返回一个仅包含该元素的流,否则为空流:

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功能有几种形式—— LongStreamIntStreamDoubleStream

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()方法适用于LongStreamIntStreamDoubleStream

2.4. Streams.mapWithIndex()

通过使用*mapWithIndex()*方法,流的每个元素都携带有关它们各自位置(索引)的信息:

mapWithIndex( Stream.of("a", "b", "c"), (str, index) -> str + ":" + index)

这将返回Stream.of(“a:0″,”b:1″,”c:2”)

使用重载的 mapWithIndex()也可以使用IntStreamLongStreamDoubleStream来实现。

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();