【问题标题】:Accumulate count of list's within another list在另一个列表中累积列表的计数
【发布时间】:2019-01-18 22:23:09
【问题描述】:

目前我有如下代码。一个嵌入在另一个列表中的列表,我想获取嵌入列表对象的总数。

我想为此写一个快速的单行器。我可以在 Java 8 中使用高效的 Lambda 或 FP 技巧吗?

int totalNo = 0;
for (ClassB classB : listOfClassB) {
    totalNo+= classB.getAnotherObjList().size();
}

【问题讨论】:

    标签: java java-8 functional-programming java-stream


    【解决方案1】:
    long totalSum = listOfClassB.stream()
         .mapToInt(elem -> elem.getAnotherObjList().size())
         .sum();
    

    我认为 sum 的结果是 long,因为几个整数可以超过最大 int 值;如果您确信它不会导致溢出,则可以随时转换它。

    至少按照上面的格式,它并不完全是单行的,但可以说它适合一个表达式。

    如果第一个列表中的元素为 null,或者如果 getAnotherObjList() 返回 null,您可以通过过滤掉这些情况来支持它:

    long totalSum = listOfClassB.stream()
         .filter(Objects::nonNull)
         .map(ClassB::getAnotherObjList)
         .filter(Objects::nonNull)
         .mapToInt(List::size)
         .sum();
    

    【讨论】:

    • 工作谢谢,如果任何对象的 getAnotherObjList 为空,上述是否会抛出空异常?还是会跳过它
    • 会的。您可以做的是过滤掉空值,让我改进答案。
    【解决方案2】:

    另一种方式,使用收集器:

    int totalNo = listOfClassB.stream()
        .collect(Collectors.summingInt(classB -> classB.getAnotherObjList().size()));
    

    等价的方式,只有方法引用:

    int totalNo = listOfClassB.stream()
        .collect(Collectors.mapping(
                 ClassB::getAnotherObjList, 
                 Collectors.summingInt(List::size)));
    

    或者在流中映射而不是在收集器中:

    int totalNo = listOfClassB.stream()
        .map(ClassB::getAnotherObjList)
        .collect(Collectors.summingInt(List::size));
    

    【讨论】:

      【解决方案3】:

      你也可以试试:

      listOfClassB.stream().map(ClassB::getAnotherObjList).flatMap(List::stream).count();
      

      这是非常简洁和优雅的。 如果ClassB::getAnotherObjList 不返回太多项目,性能不会有问题。

      【讨论】:

      • 这也是一个优雅的解决方案,尽管在实践中 cpu 效率可能较低......我想知道平面映射流实现是否会意识到它不需要展开单个列表来找出最终计数,因为可以向 Spliterator 询问估计(如果不准确)计数。
      猜你喜欢
      • 2019-05-31
      • 1970-01-01
      • 2020-09-26
      • 2020-09-14
      • 1970-01-01
      • 2019-04-29
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多