I have a Long value
that depending whether a certain list has a null as one of its fields, should be set to null and when no null is found should be set to sum of these fields of the list.
Please see my (working code) that achieves this:
Long usedBytes = bdList.stream()
.anyMatch(bd -> bd.getBytes() == null) ?
null :
bdList.stream()
.mapToLong(Backup::getBytes)
.sum();
I'm wondering why similiar and much simplier code won't set Long usedBytes
to null when there is a null as one of its fields. In this scenario Long totalUsedSpace
is set to 0L
.
Long totalUsedSpace = bdList.stream().filter(bd -> bd.bd.getBytes() != null)
.mapToLong(Backup::getBytese)
.sum();
long java.util.stream.LongStream.sum()
As you can see, LongStream
's sum
method returns a long
, not a Long
, so it can never return null
. It returns 0
when the LongStream
is empty.
Besides, if there is null
only in some of the fields, the second snippet would return the sum of the values of the non-null fields.
You can achieve your logic with a single Stream
pipeline using reduce:
Long usedBytes = bdList.stream ()
.reduce (Long.valueOf (0),
(sum,bd) -> sum == null || bd.getBytes() == null ? null : sum + bd.getBytes(),
(sum1,sum2) -> sum1 == null || sum2 == null ? null : sum1 + sum2);
I couldn't test this code, but I tested similar code that computes the sum of String lengths and returns null if any of the Strings are null:
List<String> strlist = Arrays.asList ("One","Two","Three");
Long sumOfLengths = strlist.stream ()
.reduce (Long.valueOf (0),
(sum,s) -> sum == null || s == null ? null : sum + s.length(),
(sum1,sum2) -> sum1 == null || sum2 == null ? null : sum1 + sum2);
System.out.println (sumOfLengths);
This prints
11
And if you change the input List to
List<String> strlist = Arrays.asList ("One",null,"Two","Three");
it prints
null