使用Collectors.summingLong或mapToLong来总结长整型数值。

3

我有一个包含数值的对象列表,想要汇总所有这些值。在Java 8中,最好的方法是什么?

public static void main(String[] args) {
    List<AnObject> longs = new ArrayList<AnObject>();
    longs.add(new AnObject());
    longs.add(new AnObject());
    longs.add(new AnObject());

    long mappedSum = longs.stream().mapToLong(AnObject::getVal).sum();
    long collectedSum = longs.stream().collect(Collectors.summingLong(AnObject::getVal));

    System.out.println(mappedSum);
    System.out.println(collectedSum);
}

private static class AnObject {
    private long val = 10;

    public long getVal() {
        return val;
    }
}

我认为mapToLong更加直观,但我无法解释原因。
编辑:我已经将summarizeLong更改为summingLong,因此一些答案和评论可能会有点不准确。

使用mapToLong,我想应该可以少调用一个方法。 - softarn
2
我同意mapToLong版本更清晰。另外,如果你只关心总和,可以使用Collectors.summingLong(...)代替summarizingLong(...) - Misha
@Misha 谢谢,已更新问题! - softarn
@softarn,你找到一种优雅的方式来完成它了吗?我有一个类似的情况,还需要找到getValue的长度然后将它们相加。 - Vedanth
1个回答

5

我认为使用Collectors.summarizingLong(AnObject::getVal))比你所需要的功能要多,因为它会计算除总和之外的其他统计信息(平均值、数量、最小值、最大值等)。

如果你只需要sum,请使用更简单、更有效的方法:

long mappedSum = longs.stream().mapToLong(AnObject::getVal).sum();

在您将Collectors.summarizingLong更改为Collectors.summingLong后,很难说哪个选项更有效。第一个选项有一个额外的步骤(mapToLong),但我不确定这会产生多大的差异,因为第二个选项在collect中执行的工作比第一个选项在sum中执行的工作要多。


我认为它只有在需要时才会计算这些统计数据?不确定,只是听起来很合理。 - softarn
1
根据Javadoc,@softarn可以计算所有内容 - summarizingLong ... 返回一个Collector,该Collector将长整型映射函数应用于每个输入元素,并返回结果值的摘要统计信息。一旦您在Stream上应用了该Collector,它将计算所有统计数据,无论您稍后访问的方法如何。 - Eran
1
流的特性就是看起来像是“额外步骤”的东西实际上只是它最终执行的整个操作的一部分。所以这并不是真正的区别。 - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接