Java Stream collect()方法示例

Java Stream collect() performs a mutable reduction operation on the elements of the stream. This is a terminal operation.

Java Stream collect()对流的元素执行可变的约简操作。 这是终端操作。

什么是可变归约运算? (What is Mutable Reduction Operation?)

A mutable reduction operation process the stream elements and then accumulate it into a mutable result container. Once the elements are processed, a combining function merges all the result containers to create the result.

可变还原操作处理流元素,然后将其累积到可变结果容器中。 处理完元素后,合并功能将合并所有结果容器以创建结果。

Java Stream collect()方法签名 (Java Stream collect() Method Signature)

There are two variants of Java Stream collect() method.

Java Stream collect()方法有两种变体。

  1. <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)

    <R> R收集(供应商<R>供应商,BiConsumer <R 、?超级T>累加器,BiConsumer <R,R>组合器)
  2. <R, A> R collect(Collector<? super T, A, R> collector)

    <R,A> R收集器(Collector <?super T,A,R>收集器)

The Collector is an interface that provides a wrapper for the supplier, accumulator, and combiner objects. The second method is useful when we are utilizing the Collectors class to provide built-in Collector implementation.

收集器是一个接口,为供应商,累加器和合并器对象提供包装。 当我们利用Collectors类提供内置的Collector实现时,第二种方法很有用。

The three parameters of the collect() function are:

collect()函数的三个参数是:

  1. supplier: a function that creates a new mutable result container. For the parallel execution, this function may be called multiple times and it must return a fresh value each time.

    Supplier :一个创建新的可变结果容器的函数。 对于并行执行,可以多次调用此函数,并且每次必须返回一个新值。
  2. accumulator is a stateless function that must fold an element into a result container.

    累加器是一种无状态函数,必须将元素折叠到结果容器中。
  3. combiner is a stateless function that accepts two partial result containers and merges them, which must be compatible with the accumulator function.

    组合器是一个无状态函数,它接受两个部分结果容器并将其合并,这些容器必须与累加器功能兼容。

流collect()方法示例 (Stream collect() Method Examples)

Let’s look at some examples of Stream.collect() method.

让我们看一下Stream.collect()方法的一些示例。

1.串联字符串列表 (1. Concatenating List of Strings)

Let’s say you want to concatenate the list of strings to create a new string. We can use Stream collect() function to perform a mutable reduction operation and concatenate the list elements.

假设您要连接字符串列表以创建新字符串。 我们可以使用Stream collect()函数执行可变的约简操作并连接列表元素。

List<String> vowels = List.of("a", "e", "i", "o", "u");

// sequential stream - nothing to combine
StringBuilder result = vowels.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
		(a, b) -> a.append(",").append(b));
System.out.println(result.toString());

// parallel stream - combiner is combining partial results
StringBuilder result1 = vowels.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
		(a, b) -> a.append(",").append(b));
System.out.println(result1.toString());

Output:

输出:

aeiou
a,e,i,o,u
  • The supplier function is returning a new StringBuilder object in every call.

    供应商函数在每次调用中都返回一个新的StringBuilder对象。
  • The accumulator function is appending the list string element to the StringBuilder instance.

    累加器功能将列表字符串元素附加到StringBuilder实例。
  • The combiner function is merging the StringBuilder instances. The instances are merged with each other with a comma between them.

    合并器功能正在合并StringBuilder实例。 实例彼此之间用逗号合并。
  • In the first case, we have a sequential stream of elements. So they are processed one by one and there is only one instance of StringBuilder. There is no use of the combiner function. That’s why the output produced is “aeiou”.

    在第一种情况下,我们有一个顺序的元素流。 因此,它们被一个接一个地处理,并且只有一个StringBuilder实例。 没有使用合并器功能。 这就是为什么产生的输出是“ aeiou”的原因。
  • In the second case, we have a parallel stream of strings. So, the elements are processed parallelly and there are multiple instances of StringBuilder that are being merged by the combiner function. Hence, the output produced is “a,e,i,o,u”.

    在第二种情况下,我们有并行的字符串流。 因此,元素是并行处理的,并且组合器函数正在合并StringBuilder的多个实例。 因此,产生的输出为“ a,e,i,o,u”。
  • If the stream source is ordered such as List, the collect() method maintains the order while processing. If the stream source is unordered such as Set, then the collect() method can produce different results in each invocation.

    如果流源按顺序排序(例如List) ,则collect()方法将在处理时保持顺序。 如果流源是无序的(例如Set) ,则collect()方法在每次调用中会产生不同的结果。

If you want to concatenate the list of strings, we can use the method references to reduce the code size.

如果要串联字符串列表,我们可以使用方法引用来减少代码大小。

String result2 = vowels.parallelStream()
		.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
		.toString();

2.使用collectors类将collect()流传输到列表 (2. Stream collect() to List using Collectors Class)

The Collectors class provides many useful implementations of the Collector interface. Let’s look at an example where we will filter the list of integers to select only even integers. Stream filter() is an intermediate operation and returns a stream. So, we will use the collect() function to create the list from this stream.

Collector类提供了Collector接口的许多有用的实现。 让我们看一个示例,其中我们将过滤整数列表以仅选择偶数整数。 Stream filter()是一个中间操作,返回一个流。 因此,我们将使用collect()函数从此流中创建列表。

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
		
List<Integer> evenNumbers = numbers.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println(evenNumbers);  // [2, 4, 6]

The Collectors.toList() returns a Collector implementation that accumulates the input elements into a new List.

Collectors.toList()返回一个Collector实现,该实现将输入元素累积到新的List中。

3.流collect()到集合 (3. Stream collect() to a Set)

We can use Collectors.toSet() to collect the stream elements into a new Set.

我们可以使用Collectors.toSet()将流元素收集到一个新的Set中。

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);

Set<Integer> oddNumbers = numbers.parallelStream().filter(x -> x % 2 != 0).collect(Collectors.toSet());
System.out.println(oddNumbers); // [1, 3, 5]

3.流collect()到Map (3. Stream collect() to Map)

We can use Collectors.toMap() function to collect the stream elements to a Map. This method accepts two arguments for mapping key and the corresponding value in the Map.

我们可以使用Collectors.toMap()函数将流元素收集到Map中 。 此方法接受两个用于映射键的参数和Map中的对应值。

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);

Map<Integer, String> mapOddNumbers = numbers.parallelStream().filter(x -> x % 2 != 0)
		.collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x)));
System.out.println(mapOddNumbers); // {1=1, 3=3, 5=5}

4.收集器join()示例 (4. Collectors joining() Example)

We can use Collectors joining() methods to get a Collector that concatenates the input stream CharSequence elements in the encounter order. We can use this to concatenate a stream of strings, StringBuffer, or StringBuilder.

我们可以使用Collectors join()方法来获取Collector,该Collector以遭遇顺序将输入流CharSequence元素串联在一起。 我们可以使用它来连接字符串流, StringBuffer或StringBuilder。

jshell> String value = Stream.of("a", "b", "c").collect(Collectors.joining());
value ==> "abc"

jshell> String valueCSV = Stream.of("a", "b", "c").collect(Collectors.joining(","));
valueCSV ==> "a,b,c"

jshell> String valueCSVLikeArray = Stream.of("a", "b", "c").collect(Collectors.joining(",", "{", "}"));
valueCSVLikeArray ==> "{a,b,c}"

jshell> String valueObject = Stream.of("1", new StringBuffer("2"), new StringBuilder("3")).collect(Collectors.joining());
valueObject ==> "123"

Output:

输出:

Java Stream Collect Example

Java Stream collect() Example

Java Stream collect()示例

结论 (Conclusion)

Java Stream collect() is mostly used to collect the stream elements to a collection. It’s a terminal operation. It takes care of synchronization when used with a parallel stream. The Collectors class provides a lot of Collector implementation to help us out.

Java Stream collect()通常用于将流元素收集到一个集合中。 这是终端操作。 与并行流一起使用时,它负责同步。 Collectors类提供了许多Collector实现来帮助我们。

参考资料 (References)

翻译自: https://www.journaldev.com/32457/java-stream-collect-method-examples

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值