目前,我有如下代码。一个嵌入在另一个列表中的列表,我想获取嵌入的列表对象的总数。
我想为此写一个快速的内衬。我可以在Java 8中执行高效的Lambda或FP技巧吗?
int totalNo = 0;
for (ClassB classB : listOfClassB) {
totalNo+= classB.getAnotherObjList().size();
}
答案 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));