New Stream, Comparator and Collector in Guava 21 – Guava中的新流、比较器和收集器 21

最后修改: 2017年 3月 23日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

This article is first in the series about the new features launched with Version 21 of the Google Guava library. We’ll discuss newly added classes and some major changes from previous versions of Guava.

本文是关于Google Guava库第21版推出的新功能系列的第一篇文章。我们将讨论新增加的类和Guava以前版本的一些主要变化。

More specifically, we’ll discuss additions and changes in the common.collect package.

更具体地说,我们将讨论 common.collect包中的新增内容和变化。

Guava 21 introduces some new and useful functionality in the common.collect package; let’s have a quick look at some of these new utilities and how we can get the most out of them.

Guava 21在common.collect包中引入了一些新的、有用的功能;让我们快速浏览一下这些新的实用程序,以及我们如何能够充分利用它们。

2. Streams

2.

We’re all excited about the latest addition of java.util.stream.Stream in Java 8. Well, Guava is now making good use of streams and provides what Oracle may have missed.

我们都对Java 8中最新增加的java.util.stream.Stream感到兴奋。那么,Guava现在很好地利用了流,并提供了Oracle可能错过的东西。

Streams is a static utility class, with some much-needed utilities for handling Java 8 streams.

Streams是一个静态的实用类,有一些处理Java 8流的急需的实用工具。

2.1. Streams.stream()

2.1.Streams.stream()

Streams class provides four ways to create streams using Iterable, Iterator, Optional and Collection.

Streams类提供了四种创建流的方法,使用IterableIteratorOptionalCollection

Though, stream creation using Collection is deprecated, as it’s provided by Java 8 out of the box:

不过,使用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 class also provides flavors with OptionalDouble, OptionalLong and OptionalInt. These methods return a stream containing only that element otherwise empty stream:

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

2.2.Streams.concat()

Streams class provides methods for concating more than one homogeneous streams.

Streams类提供了用于连接多个同质流的方法。

Stream<Integer> concatenatedStreams = Streams.concat(streamFromCollection, streamFromIterable,streamFromIterator);

The concat functionality comes in a few flavors – LongStream, IntStream and DoubleStream.

concat功能有几种类型 – LongStreamIntStreamDoubleStream

2.3. Streams.findLast()

2.3.Streams.findLast()

Streams have a utility method to find the last element in the stream by using findLast() method.

Streams有一个实用方法,通过使用findLast()方法找到流中的最后一个元素。

This method either returns last element or Optional.empty() if the stream is there are no elements in the stream:

如果流中没有任何元素,该方法要么返回最后一个元素,要么返回Optional.empty()

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Optional<Integer> lastItem = Streams.findLast(integers.stream());

The findLast() method works for LongStream, IntStream and DoubleStream.

findLast()方法适用于LongStreamIntStreamDoubleStream

2.4. Streams.mapWithIndex()

2.4.Streams.mapWithIndex()

By using mapWithIndex() method, each element of the stream carries information about their respective position (index):

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

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

This will return Stream.of(“a:0″,”b:1″,”c:2”).

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

Same can be achieved with IntStream, LongStream and DoubleStream using overloaded mapWithIndex().

对于IntStreamLongStreamDoubleStream,使用重载的mapWithIndex()也可以实现同样的效果。

2.5. Streams.zip()

2.5.Streams.zip()

In order to map corresponding elements of two streams using some function, just use zip method of Streams:

为了使用一些函数来映射两个流的相应元素,只需使用Streams:的zip方法即可。

Streams.zip(
  Stream.of("candy", "chocolate", "bar"),
  Stream.of("$1", "$2","$3"),
  (arg1, arg2) -> arg1 + ":" + arg2
);

This will return Stream.of(“candy:$1″,”chocolate:$2″,”bar:$3”);

这将返回Stream.of(“candy:1″, “chocolate:2″, “bar:3″);

The resulting stream will only be as long as the shorter of the two input streams; if one stream is longer, its extra element will be ignored.

产生的流将只与两个输入流中较短的那个一样长;如果一个流较长,它的额外元素将被忽略。

3. Comparators

3.比较器

Guava Ordering class is deprecated and in the phase of deletion in newer versions. Most of the functionalities of Ordering class are already enlisted in JDK 8.

Guava的Ordering类已被废弃,在新的版本中处于删除阶段。Ordering类的大部分功能都已经在JDK 8中被收录。

Guava introduces Comparators to provide additional features of Ordering which are not yet provided by the Java 8 standard libs.

Guava引入了Comparators来提供Ordering的额外功能,这些功能尚未被Java 8标准库所提供。

Let’s have a quick look at these.

让我们快速看一下这些。

3.1. Comparators.isInOrder()

3.1.Comparators.isInOrder()

This method returns true if each element in the Iterable is greater than or equal to the preceding one, as specified by the Comparator:

如果Iterable中的每个元素都大于或等于前面的元素,该方法返回true,如Comparator所指定。

List<Integer> integers = Arrays.asList(1,2,3,4,4,6,7,8,9,10);
boolean isInAscendingOrder = Comparators.isInOrder(
  integers, new AscedingOrderComparator());

3.2. Comparators.isInStrictOrder()

3.2.Comparators.isInStrictOrder()

Quite similar to the isInOrder() method but it strictly holds the condition, the element cannot be equal to the preceding one, it has to be greater than. The previous code will return false for this method.

isInOrder()方法相当类似,但它严格掌握条件,元素不能等于前一个,必须大于。前面的代码对于这个方法将返回false。

3.3. Comparators.lexicographical()

3.3.Comparators.lexicographical()

This API returns a new Comparator instance – which sorts in lexicographical (dictionary) order comparing corresponding elements pairwise. Internally, it creates a new instance of LexicographicalOrdering<S>().

这个API返回一个新的Comparator实例–它以词典(dictionary)的顺序对相应的元素进行配对排序。在内部,它创建了一个新的LexicographicalOrdering<S>()/em>实例。

4. MoreCollectors

4.更多收藏家

MoreCollectors contains some very useful Collectors which are not present in Java 8 java.util.stream.Collectors and are not associated with com.google.common type.

MoreCollectors包含一些非常有用的Collectors,这些Collectors在Java 8 java.util.stream.Collectors中不存在,也没有与com.google.common类型相关。

Let’s go over a few of these.

让我们来看看其中的几个问题。

4.1. MoreCollectors.toOptional()

4.1.MoreCollectors.toOptional()

Here, Collector converts a stream containing zero or one element to an Optional:

这里,Collector将一个包含零或一个元素的流转换为Optional

List<Integer> numbers = Arrays.asList(1);
Optional<Integer> number = numbers.stream()
  .map(e -> e * 2)
  .collect(MoreCollectors.toOptional());

If the stream contains more than one elements – the collector will throw IllegalArgumentException.

如果流中包含一个以上的元素–采集器将抛出IllegalArgumentException.

4.2. MoreCollectors.onlyElement()

4.2.MoreCollectors.onlyElement()

With this API, the Collector takes a stream containing just one element and returns the element; if the stream contains more than one element it throws IllegalArgumentException or if the stream contains zero element it throws NoSuchElementException.

通过这个API,Collector接收一个只包含一个元素的流并返回该元素;如果该流包含一个以上的元素,它会抛出IllegalArgumentException,或者如果该流包含零元素,它会抛出NoSuchElementException

5. Interners.InternerBuilder

5.Interners.InternerBuilder

This is an internal builder class to already existing Interners in Guava library. It provides some handy method to define concurrency level and type (weak or strong) of Interner you prefer:

这是Guava库中已有的Interners的内部构建类。它提供了一些方便的方法来定义并发级别和类型(弱或强)的Interner,你喜欢。

Interners interners = Interners.newBuilder()
  .concurrencyLevel(2)
  .weak()
  .build();

6. Conclusion

6.结论

In this quick article, we explored the newly added functionality in the common.collect package of Guava 21.

在这篇快速文章中,我们探讨了Guava 21的common.collect包中新增加的功能。

The code for this article can be found on Github, as always.

本文的代码可以在Github上找到,一如既往。