Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding a java.lang.NullPointerException being thrown while performing arithmetic operations on a collection of values using lambda expressions

Given a list of values to sum up.

List<CartItems> cartItems = ...

BigDecimal totalWeight = cartItems.stream().reduce(BigDecimal.ZERO, (weight, cart)
        -> weight.add(cart.getProduct().getWeight().multiply(BigDecimal.valueOf(cart.getQty()))), BigDecimal::add)
        .setScale(SCALE, RoundingMode.HALF_UP);

Here, cart.getProduct().getWeight() may be null at anytime, since it is an optional field. This will thus throw a java.lang.NullPointerException, if one of the items contains a null value in the weight field of type java.math.BigDecmial.

What is the most concise way to avoid a java.lang.NullPointerException being thrown when an item in a given collection contains a null value other than imposing a nasty conditional check like the following?

BigDecimal totalWeight = products.stream().reduce(BigDecimal.ZERO, (weight, cart)
        -> weight.add(cart.getProduct().getWeight() == null ? BigDecimal.ZERO : cart.getProduct().getWeight().multiply(BigDecimal.valueOf(cart.getQty()))), BigDecimal::add)
        .setScale(SCALE, RoundingMode.HALF_UP);

Similarly, the following will also throw a java.lang.NullPointerException, since the given list contains a null value in it.

List<Integer> list = new ArrayList<Integer>() {{
        add(1);
        add(2);
        add(3);
        add(null);
        add(5);
    }};

Integer sum = list.stream().reduce(0, Integer::sum); // Or
//Integer sum = list.stream().reduce(0, (a, b) -> a + b);

System.out.println("sum : " + sum);
like image 289
Tiny Avatar asked Mar 04 '16 21:03

Tiny


People also ask

How do I overcome Java Lang NullPointerException?

How to avoid the NullPointerException? To avoid the NullPointerException, we must ensure that all the objects are initialized properly, before you use them. When we declare a reference variable, we must verify that object is not null, before we request a method or a field from the objects.

What causes Java Lang NullPointerException?

Some of the common reasons for NullPointerException in java programs are: Invoking a method on an object instance but at runtime the object is null. Accessing variables of an object instance that is null at runtime. Throwing null in the program.

What does NullPointerException mean in Java?

NullPointerException is a RuntimeException . In Java, a special null value can be assigned to an object reference. NullPointerException is thrown when an application attempts to use an object reference that has the null value. These include: Calling an instance method on the object referred by a null reference.


2 Answers

I think the problem is more with the reduce. You try to do to many things in one function. As I understand it, you want the sum of weight*qty for each cart. I would cut the operation like this:

BigDecimal totalWeight = cartItems.stream()
        .filter(cart -> cart != null
                && cart.getProduct() != null 
                && cart.getProduct().getWeight() != null)
        .map(cart -> cart.getProduct().getWeight().multiply(BigDecimal.valueOf(cart.getQty())))
        .reduce(BigDecimal.ZERO, BigDecimal::add)
        .setScale(SCALE, RoundingMode.HALF_UP);
like image 82
njzk2 Avatar answered Sep 22 '22 13:09

njzk2


Here are couple of solutions for this problem.

        List<Integer> list = Arrays.asList(new Integer[]{
                1,
                2,
                3,
                (Integer)null,
                5,
        });

        Integer sum = list.stream().map(i -> i != null ? i : 0).reduce(0, Integer::sum); 

Or

list.replaceAll(s -> s == null ? 0 : s);
Integer sum = list.stream().reduce(0, Integer::sum);
like image 38
Raghu K Nair Avatar answered Sep 22 '22 13:09

Raghu K Nair