Java Stream collect() 对流元素执行一个可变减少操作,这是一个终端操作。
什么是可变减少操作?
一个可变减少操作处理流元素,然后将其积累成一个可变结果容器. 一旦元素被处理,一个组合函数将所有结果容器合并来创建结果。
Java 流收集() 方法签名
有两种版本的 [Java 流]( / 社区 / 教程 / java-8 流) collect() 方法。
R收集(供应商 供应商, BiConsumer<R,?超级T>电池,BiConsumer<R,R>组合器) - <R,A> R收集(收集器<?超级T,A,R>收集器)
Collector 是一个为供应商、蓄积器和组合器对象提供包装的界面,第二种方法在我们使用 Collectors 类来提供内置的 Collector 实现时是有用的。
- 供应商:创建一个新的可变结果容器的函数. 对于平行执行,该函数可以被调用多次,并且每次必须返回新值
- 蓄电器是一个无状态函数,必须将一个元素折叠成一个结果容器
- 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() 主要用于收集到集合中的流元素. 这是一个终端操作. 它在使用与平行流时负责同步。