Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accumulate count of list's within another list

Currently i have code like below. A list embedded with in another list, and i want to get the total count of the embedded list objects.

I want to write a quick oneliner for this. Is there an efficient Lambda or FP trick i can do in Java 8?

int totalNo = 0;
for (ClassB classB : listOfClassB) {
    totalNo+= classB.getAnotherObjList().size();
}
like image 317
Saad Avatar asked Jan 18 '19 22:01

Saad


Video Answer


3 Answers

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

I think the result of sum is a long as several integers can go past the max int value; you can always cast it if you are confident that it won't result in overflow.

It is not quite a one-liner at least as formatted above but arguably it fits in a single expression.

In case and element in the first list is null or if getAnotherObjList() returns a null you can support that by filtering out those cases:

long totalSum = listOfClassB.stream()
     .filter(Objects::nonNull)
     .map(ClassB::getAnotherObjList)
     .filter(Objects::nonNull)
     .mapToInt(List::size)
     .sum();
like image 158
Valentin Ruano Avatar answered Oct 17 '22 20:10

Valentin Ruano


Another way, using collectors:

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

An equivalent way, only with method references:

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

Or mapping in the stream instead of in the collector:

int totalNo = listOfClassB.stream()
    .map(ClassB::getAnotherObjList)
    .collect(Collectors.summingInt(List::size));
like image 42
fps Avatar answered Oct 17 '22 21:10

fps


You can also try:

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

This is very concise and elegant. If ClassB::getAnotherObjList does not return too many items performance would not be a problem.

like image 2
fastcodejava Avatar answered Oct 17 '22 20:10

fastcodejava