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

最后修改: 2017年 3月 23日

1. Introduction


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


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

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

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

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


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


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 =;
Stream<Integer> streamFromIterator =;
Stream<Integer> streamFromIterable =<Integer>) numbers);
Stream<Integer> streamFromOptional =;

Streams class also provides flavors with OptionalDouble, OptionalLong and OptionalInt. These methods return a stream containing only that element otherwise empty stream:


LongStream streamFromOptionalLong =;
IntStream streamFromOptionalInt =;
DoubleStream streamFromOptionalDouble =;

2.2. Streams.concat()


Streams class provides methods for concating more than one homogeneous 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()


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


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


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

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


2.4. Streams.mapWithIndex()


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


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



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

  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


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


This method returns true if each element in the Iterable is greater than or equal to the preceding one, as specified by the 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()


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.


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


4. MoreCollectors


MoreCollectors contains some very useful Collectors which are not present in Java 8 and are not associated with type.

MoreCollectors包含一些非常有用的Collectors,这些Collectors在Java 8中不存在,也没有与类型相关。

Let’s go over a few of these.


4.1. MoreCollectors.toOptional()


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


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

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


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.


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:


Interners interners = Interners.newBuilder()

6. Conclusion


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.