Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I avoid NullPointerExceptions in lambda comparators?

I want to compare two given objects which might be null at runtime. In my example:

@Test
public void shouldCompareAgents() {

    Agent a1 = new Agent();
    a1.setId("4711");
    a1.setType(null);

    Agent a2 = new Agent();
    a2.setId(a1.getId());
    a2.setType(a1.getType());

    assertEquals("Agent.getId", 0,
            Comparator.comparing(Agent::getId).compare(a1, a2));

    assertEquals("Agent.getType", 0,
            Comparator.comparing(Agent::getType).compare(a1, a2));
}

The assertion by id works fine, by type does not as a1.getType() is null. Is there a way to avoid this? I tried Comparator.nullsLast(...), but that makes no sense as I am not sorting elements here.

I have lots of assertions to do, so I'd prefer "a one-liner". I am new to lambda expressions.

like image 510
JaneDoe Avatar asked Dec 06 '17 13:12

JaneDoe


People also ask

How does comparator handle null values?

When both elements are null, then they are considered equal. When both elements are non-null, the specified Comparator determines the order. If specified comparator is null, then the returned comparator considers all non-null elements equal.

How do you use lambda comparator?

A lambda expression used with any functional interface and Comparator is a functional interface. The Comparator interface has used when sorting a collection of objects compared with each other. In the below example, we can sort the employee list by name using the Comparator interface.


2 Answers

If you just want to use this in a JUnit test, why don't you just pass the objects you want to compare directly to the assertEquals method?

assertEquals("Agent.getId", a1.getId(), a2.getId());

This also helps JUnit to generate a useful error message when the test fails.

If you want to do this in production code, you can use Objects.equals:

if (Objects.equals(a1.getId(), a2.getId())) { ... }

which is present since Java 7.

like image 144
Hoopje Avatar answered Oct 12 '22 10:10

Hoopje


Something like this:

Comparator.comparing(Agent::getType, 
    Comparator.nullsLast(Comparator.naturalOrder()))

Since you need this to be used in more places, you can extract it as :

    private static <R, T extends Comparable<T>> boolean areEqual(R left, R right, Function<R, T> function) {
         return Comparator.comparing(
                 function, 
                 Comparator.nullsLast(Comparator.naturalOrder())) 
                           .compare(left, right) == 0;
}
like image 44
Eugene Avatar answered Oct 12 '22 09:10

Eugene