Stream API为我们提供了Stream.reduce
用来实现集合元素的归约。reduce函数有三个参数:
Identity
标识:一个元素,它是归约操作的初始值,如果流为空,则为默认结果。
Accumulator
累加器:具有两个参数的函数:归约运算的部分结果和流的下一个元素。
Combiner
合并器(可选):当归约并行化时,或当累加器参数的类型与累加器实现的类型不匹配时,用于合并归约操作的部分结果的函数。
注意观察上面的图,我们先来理解累加器:
阶段累加结果作为累加器的第一个参数
集合遍历元素作为累加器的第二个参数
Integer类型归约
reduce初始值为0,累加器可以是lambda表达式,也可以是方法引用。
1
2
3
4
5
6
7
8
9
10
|
List<Integer> numbers = Arrays.asList( 1 , 2 , 3 , 4 , 5 , 6 ); int result = numbers .stream() .reduce( 0 , (subtotal, element) -> subtotal + element); System.out.println(result); //21 int result = numbers .stream() .reduce( 0 , Integer::sum); System.out.println(result); //21 |
String类型归约
不仅可以归约Integer类型,只要累加器参数类型能够匹配,可以对任何类型的集合进行归约计算。
1
2
3
4
5
6
7
8
9
|
List<String> letters = Arrays.asList( "a" , "b" , "c" , "d" , "e" ); String result = letters .stream() .reduce( "" , (partialString, element) -> partialString + element); System.out.println(result); //abcde String result = letters .stream() .reduce( "" , String::concat); System.out.println(result); //ancde |
复杂对象归约
计算所有的员工的年龄总和。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Employee e1 = new Employee( 1 , 23 , "M" , "Rick" , "Beethovan" ); Employee e2 = new Employee( 2 , 13 , "F" , "Martina" , "Hengis" ); Employee e3 = new Employee( 3 , 43 , "M" , "Ricky" , "Martin" ); Employee e4 = new Employee( 4 , 26 , "M" , "Jon" , "Lowman" ); Employee e5 = new Employee( 5 , 19 , "F" , "Cristine" , "Maria" ); Employee e6 = new Employee( 6 , 15 , "M" , "David" , "Feezor" ); Employee e7 = new Employee( 7 , 68 , "F" , "Melissa" , "Roy" ); Employee e8 = new Employee( 8 , 79 , "M" , "Alex" , "Gussin" ); Employee e9 = new Employee( 9 , 15 , "F" , "Neetu" , "Singh" ); Employee e10 = new Employee( 10 , 45 , "M" , "Naveen" , "Jain" ); List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); Integer total = employees.stream().map(Employee::getAge).reduce( 0 ,Integer::sum); System.out.println(total); //346 |
先用map将Stream流中的元素由Employee类型处理为Integer类型(age)。
然后对Stream流中的Integer类型进行归约
Combiner合并器的使用
除了使用map函数实现类型转换后的集合归约,我们还可以用Combiner合并器来实现,这里第一次使用到了Combiner合并器。 因为Stream流中的元素是Employee,累加器的返回值是Integer,所以二者的类型不匹配。这种情况下可以使用Combiner合并器对累加器的结果进行二次归约,相当于做了类型转换。
1
2
3
|
Integer total3 = employees.stream() .reduce( 0 ,(totalAge,emp) -> totalAge + emp.getAge(),Integer::sum); //注意这里reduce方法有三个参数 System.out.println(total); //346 |
计算结果和使用map进行数据类型转换的方式是一样的。
并行流数据归约(使用合并器)
对于大数据量的集合元素归约计算,更能体现出Stream并行流计算的威力。
在进行并行流计算的时候,可能会将集合元素分成多个组计算。为了更快的将分组计算结果累加,可以使用合并器。
1
2
3
4
5
|
Integer total2 = employees .parallelStream() .map(Employee::getAge) .reduce( 0 ,Integer::sum,Integer::sum); //注意这里reduce方法有三个参数 System.out.println(total); //346 |
以上就是java理论基础Stream reduce实现集合元素归约的详细内容,更多关于java Stream reduce集合元素归约的资料请关注服务器之家其它相关文章!
原文链接:https://zimug.blog.csdn.net/article/details/107055398