简体   繁体   English

Java8 Lambda表达式评估

[英]Java8 Lambda Expressions Evaluation

List <Person> roster = new List<Person>();    
Integer totalAgeReduce = roster
  .stream()
  .map(Person::getAge)
  .reduce(
      0,
      (a, b) -> a + b);

Can anyone help me understand the above code snippet. 谁能帮我理解上面的代码片段。 My understanding is that the stream method will first iterate through the entire roster List and while it is iterating it will create a new List of the mapped objects with every person's age in it. 我的理解是,stream方法将首先迭代整个花名册List并且在迭代时将创建一个包含每个人年龄的映射对象的新List Then it will finally call the reduce after the mapping is done (the reduce is only called at the end after mapping correct?). 然后,它将在映射完成后最终调用reduce(仅在映射正确之后才调用reduce吗?)。 And in the reduce it starts of at 0, and in the first iteration of reduce on the newly mapped list a = 0 and b is equal to the first element in the List that was created from the mapping function. 并且在化简中,它从0开始,并且在新映射列表上的化简的第一次迭代中, a = 0和b等于List中从映射函数创建的第一个元素。 Then it will continue and add all the elements from the mapped list and return to you an integer with the sum of all the ages. 然后它将继续并添加映射列表中的所有元素,并返回一个包含所有年龄之和的整数。

TL;DR TL; DR

It sums all the ages from the Person's within the List. 它汇总了列表中“人员”的所有年龄。


stream() : Creates a stream from the Collection (List) stream() :从集合(列表)创建流

map() : Will make a mapping from the received object to another object (here from Person to Integer (getAge returns an Integer)) map() :将接收到的对象映射到另一个对象(这里是从Person到Integer(getAge返回Integer))

reduce(0,(a, b) -> a + b) : reduce is a reduction (it reduces all the objects received into one (here the action is to add them all together, a big addition). It takes the identity (first value to begin with) as first argument and the following lambda expression ( BinaryOperator<Integer> or BiFunction<Integer, Integer, Integer> ) presents the logic to apply for the reduction. reduce(0,(a, b) -> a + b)reduce是一个减少项(它将接收到的所有对象减少为一个(此处的操作是将它们全部加在一起,是一个很大的加法)。它采用标识(以第一个值开头)作为第一个参数,随后的lambda表达式( BinaryOperator<Integer>BiFunction<Integer, Integer, Integer> )提出了适用于归约的逻辑。


Example

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

Each item in the stream will each be sent through all the steps one at a time. 流中的每个项目将一次通过所有步骤发送。 Here's some test code to help you see whats happening: 以下是一些测试代码,可帮助您了解发生了什么:

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; })
);

Output 输出量

1 A
2 A
3 A
1 B
2 B
3 B
END: AB

The thing is 事情是

 (a, b) -> a + b);

is an accumulator, and if you look at it like a recursive function, it will be passing the result of the sum, for every element in the stream, as Andreas Point out is not a list, is a pipeline. 是一个累加器,如果您像递归函数那样看它,它将传递总和的结果,对于流中的每个元素,因为Andreas Point out不是列表,而是一个管道。

Just to point out lambda expressions is just passing an Argument which in fact is a function . 仅仅指出lambda表达式只是传递一个参数,它实际上是一个函数

If you would use loops it would look like this: 如果要使用循环,它将看起来像这样:

List<Integer> ages = new ArrayList<>();
for (Person p : roster) {
    ages.add(p.getAge());
}

int sum = 0;
for (Integer age : ages) {
    sum += age;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM