Java 8 Lambdas:将 Stream 映射为 Integer 类型然后调用 sum() 不会编译

新手上路,请多包涵

我在玩 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 类型时,有什么方法可以使它工作吗?

提前致谢

原文由 Daniel K. 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 642
2 个回答

我认为他们正在改变方法

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 邮件列表,他们想听听真实世界的经验。

原文由 ZhongYu 发布,翻译遵循 CC BY-SA 3.0 许可协议

他们没有改变方法,这两种方法都可用,因为 map () 是返回 Stream 的通用方法,并且他们将 int、long、double Stream 分离到单独的方法中,例如 mapToInt ()、 mapToLong () 和 mapToDouble ().

是的,你可以使用 reduce() 方法

reduce(T identity, BinaryOperator< T > 累加器)

使用关联累加函数对该流的元素执行缩减,并返回描述缩减值的 Optional(如果有)。

reduce() 的工作原理:假设我们有 int 数组流,我们应用 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;
    }
}

原文由 pardeep131085 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题