Avoid NoSuchElementException in Java 8 streams
This problem is a follow-up to the earlier problem: adding up bigdecisions using streams
The problem is related to adding bigdecimals using java 8 streams and lambda expressions After implementing the answer given, I encountered another problem: whenever the stream is empty, the optional:: get () method will throw NoSuchElementException
Consider the following codes:
public static void main(String[] args){ LinkedList<BigDecimal> values = new LinkedList<>(); // values.add(BigDecimal.valueOf(.1)); // values.add(BigDecimal.valueOf(1.1)); // values.add(BigDecimal.valueOf(2.1)); // values.add(BigDecimal.valueOf(.1)); // Classical Java approach BigDecimal sum = BigDecimal.ZERO; for(BigDecimal value : values) { System.out.println(value); sum = sum.add(value); } System.out.println("Sum = " + sum); // Java 8 approach values.forEach((value) -> System.out.println(value)); System.out.println("Sum = " + values.stream().reduce((x,y) -> x.add(y)).get()); }
Vanilla java code has no problem with empty sets, but the new Java 8 code can
What is the most elegant way to avoid using nsee here? Of course, we can do this:
System.out.println("Sum = " + values == null || values.isEmpty() ? 0 : values.stream().reduce((x,y) -> x.add(y)).get());
But is there a java-8-ish way to handle empty collections?
Solution
In this case, you should not use the reduce version that can return optional < BigDecimal >
You should use another version, as mentioned earlier, to provide the identity element when the stream is empty, which is the whole reason why the identity element exists
So you want to have:
System.out.println("Sum = " + values.stream().reduce(BigDecimal.ZERO,(x,y) -> x.add(y));
Not the old version
In this case, you don't care if the flow is empty, you just need a valid result