累积另一个列表中的列表数

时间:2019-01-18 22:23:10

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

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

我想为此写一个快速的内衬。我可以在Java 8中执行高效的Lambda或FP技巧吗?

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

3 个答案:

答案 0 :(得分:9)

long totalSum = listOfClassB.stream()
     .mapToInt(elem -> elem.getAnotherObjList().size())
     .sum();

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

它至少不是上面那样格式化的单行,但可以说它适合单个表达式。

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

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

答案 1 :(得分:2)

您也可以尝试:

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

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

答案 2 :(得分: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));