Java 流 collect() 方法示例

Java Stream collect() 对流元素执行一个可变减少操作,这是一个终端操作。

什么是可变减少操作?

一个可变减少操作处理流元素,然后将其积累成一个可变结果容器. 一旦元素被处理,一个组合函数将所有结果容器合并来创建结果。

Java 流收集() 方法签名

有两种版本的 [Java 流]( / 社区 / 教程 / java-8 流) collect() 方法。

  1. R收集(供应商供应商, BiConsumer<R,?超级T>电池,BiConsumer<R,R>组合器)
  2. <R,A> R收集(收集器<?超级T,A,R>收集器)

Collector 是一个为供应商、蓄积器和组合器对象提供包装的界面,第二种方法在我们使用 Collectors 类来提供内置的 Collector 实现时是有用的。

  1. 供应商:创建一个新的可变结果容器的函数. 对于平行执行,该函数可以被调用多次,并且每次必须返回新值
  2. 蓄电器是一个无状态函数,必须将一个元素折叠成一个结果容器
  3. combiner是一个无状态函数,它接受两个部分结果容器并合并它们,这必须与蓄电器函数兼容

流收集() 方法示例

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

1、连接字符串列表

假设您想要连接字符串列表以创建新的字符串,我们可以使用流收集()函数执行可变减少操作并连接列表元素。

 1List<String> vowels = List.of("a", "e", "i", "o", "u");
 2
 3// sequential stream - nothing to combine
 4StringBuilder result = vowels.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
 5    	(a, b) -> a.append(",").append(b));
 6System.out.println(result.toString());
 7
 8// parallel stream - combiner is combining partial results
 9StringBuilder result1 = vowels.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
10    	(a, b) -> a.append(",").append(b));
11System.out.println(result1.toString());

输出:

1aeiou
2a,e,i,o,u
  • 联合国 供货商功能是返回每个调用中的新对象 [StringBuilder] (/community/touris/java-stringbuilder)
  • 累积函数将列表字符串元素附加到 StringBuilder 实例中( _) ( )* 组合函数正在合并 StringBuilder 实例 。 实例相互合并,相互之间加一个逗号。
  • 在第一种情况下,我们有一系列的元素。 因此,它们逐一处理,只有一例StringBuilder。 组合函数没有用. 这就是为什么产出是"aeiou"(). ( )* 在第二种情况下,我们有一个平行的串流。 因此,这些元素是平行处理的,并且有多个StringBuilder的例子被组合函数所合并. 因此,产出为"a,e,i,o,u" . 如果流源被命令如 [List] (/community/tourises/java-list),收集方法在处理时维持了顺序. 如果流源没有顺序,例如Set,那么收集方法在每次引用时可以产生不同的结果. () (英语)

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

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

2. 流 collect() 到 List 使用 Collectors 类

Collectors 类提供了许多有用的 Collector 界面实现方案. 让我们看看一个例子,我们将过滤整数列表,只选择整数。 Stream filter()是一个中间操作,返回一个流。

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

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

流收集() 到 Set

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

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

流收集() 到地图

我们可以使用 Collectors.toMap() 函数来收集流元素到 Map

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

集合者加入() 示例

我们可以使用 Collectors joining() 方法来获取一个 Collector 将 CharSequence 输入流元素合并到 encounter 顺序中,我们可以使用此方法合并一个字符串的流程, StringBuffer,或 StringBuilder。

 1jshell> String value = Stream.of("a", "b", "c").collect(Collectors.joining());
 2value ==> "abc"
 3
 4jshell> String valueCSV = Stream.of("a", "b", "c").collect(Collectors.joining(","));
 5valueCSV ==> "a,b,c"
 6
 7jshell> String valueCSVLikeArray = Stream.of("a", "b", "c").collect(Collectors.joining(",", "{", "}"));
 8valueCSVLikeArray ==> "{a,b,c}"
 9
10jshell> String valueObject = Stream.of("1", new StringBuffer("2"), new StringBuilder("3")).collect(Collectors.joining());
11valueObject ==> "123"

输出:

Java Stream Collect Example

结论

Java Stream collect() 主要用于收集到集合中的流元素. 这是一个终端操作. 它在使用与平行流时负责同步。

参考

Published At
Categories with 技术
Tagged with
comments powered by Disqus