我正在玩Java8 lambda表达式。作为一个例子,我然后尝试总结列表中包含的年龄:
import java.util.Arrays;
import java.util.List;
public class Person {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(new Person("FooBar", 12), new Person("BarFoo", 16));
Integer sumOfAges = persons.stream().map(Person::getAge).sum();
System.out.println("summedUpAges: " + sumOfAges);
}
private final String name;
private final Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
当我尝试使用以下java编译器编译此代码段时:
openjdk version "1.8.0-ea"
OpenJDK Runtime Environment (build 1.8.0-ea-lambda-night
OpenJDK 64-Bit Server VM (build 25.0-b21, mixed mode)
我收到以下编译错误:
java: cannot find symbol
symbol: method sum()
location: interface java.util.stream.Stream<java.lang.Integer>
但是如果我将getAge()方法的返回值从Integer更改为int,我会得到预期的结果。但有时候不可能或不希望在飞行中更改签名。当getAge()返回一个Integer类型时,有没有办法让它工作?
提前致谢, 丹尼尔
答案 0 :(得分:17)
我认为他们正在改变方法
IntStream map(ToIntFunction<? super T> mapper)
到
IntStream mapToInt(ToIntFunction<? super T> mapper)
然后你的
persons.stream().mapToInt(Person::getAge).sum()
无论getAge()
是int
还是Integer
,始终有效。
请参阅此主题:http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-March/001480.html
顺便说一句,你可以将你的问题发布到lambda-dev邮件列表,他们希望听到真实世界的经历。
答案 1 :(得分:2)
他们没有改变方法,两者都可用,因为 map ()是一个返回Stream的通用方法,他们将int,long,double Stream分成单独的方法,如as mapToInt (), mapToLong ()和 mapToDouble ()。
是的,您可以使用reduce()方法
reduce(T identity,BinaryOperator&lt; T&gt; accumulator)
使用关联累加函数对此流的元素执行减少,并返回描述减少值的Optional(如果有)。
reduce()如何工作:假设我们有int数组流并且我们应用reduce函数
reduce(0,(l,r) - > l + r)
在诸如1,2,3,4和5的整数列表中,种子0被添加到1,结果(1)被存储为累积值,然后作为左手值除了作为流中的下一个数字(1 + 2)。结果(3)作为累计值存储并用于下一次加法(3 + 3)。结果(6)存储并用于下一次加法(6 + 4),结果用于最终加法(10 + 5),得到最终结果15。
所以你的例子看起来像:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Person {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(new Person("FooBar", 12), new Person("BarFoo", 16));
Stream<Integer> stream = persons.stream().map(x -> x.getAge());
int sum = stream.reduce(0, (l, r) -> l + r);
System.out.println(sum);
}
private final String name;
private final Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
答案 2 :(得分:0)
要添加bayou.io回答,我更喜欢lambda表达式而不是方法引用。
persons.stream().mapToInt(x->x.getAge()).sum();