List <Person> roster = new List<Person>();
Integer totalAgeReduce = roster
.stream()
.map(Person::getAge)
.reduce(
0,
(a, b) -> a + b);
谁能帮我理解上面的代码片段。我的理解是,流方法将首先遍历整个花名册List
,在迭代时,它将创建一个映射对象的新List
,其中包含每个人的年龄。然后它会在映射完成后最终调用 reduce(映射正确后仅在最后调用 reduce?在reduce中,它从0开始,在新映射列表reduce的第一次迭代中,a = 0
和b等于从映射函数创建的List
中的第一个元素。然后它将继续添加映射列表中的所有元素,并返回一个包含所有年龄总和的整数。
流中的每个项目将逐个发送所有步骤。下面是一些测试代码,可帮助您了解发生的情况:
List<String> test = Arrays.asList("A","B");
System.out.println("END: " + test.stream()
.map(s -> {System.out.println("1 " + s); return s; })
.map(s -> {System.out.println("2 " + s); return s; })
.reduce("", (acc, s) -> {System.out.println("3 " + s); return acc + s; })
);
输出
1 A
2 A
3 A
1 B
2 B
3 B
END: AB
TL;DR
它汇总了名单中该人的所有年龄。
stream()
:从集合创建流(列表(
map()
:将从接收的对象映射到另一个对象(此处从 Person 到 Integer(getAge 返回一个 Integer((
reduce(0,(a, b) -> a + b)
:reduce
是减少(它将接收到的所有对象减少为一个(这里的动作是将它们全部加在一起,这是一个很大的加法(。它以恒等式(第一个值开头(作为第一个参数,下面的lambda表达式(BinaryOperator<Integer>
或BiFunction<Integer, Integer, Integer>
(表示应用于约简的逻辑。
例
List<Person> persons = Arrays.asList(new Person("John", 20),
new Person("Mike", 40),
new Person("Wayne", 30));
Integer totalAgeReduce = roster.stream()
.map(Person::getAge)
.reduce(0,(a, b) -> a + b);
System.out.println(totalAgeReduce); // 90
问题是
(a, b) -> a + b);
是一个累加器,如果你把它看成一个递归函数,它将为流中的每个元素传递总和的结果,因为 Andreas Point 不是一个列表,而是一个管道。
只是指出lambda表达式只是传递一个参数,它实际上是一个函数。
如果你使用循环,它看起来像这样:
List<Integer> ages = new ArrayList<>();
for (Person p : roster) {
ages.add(p.getAge());
}
int sum = 0;
for (Integer age : ages) {
sum += age;
}