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();
}
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();
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));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With