2017-12-06 169 views
12

Chcę porównać dwa dane obiekty, które mogą być zerowe w czasie wykonywania. W moim przykładzie:Jak uniknąć wyjątków NullPointerExceptions w komparatory lambda?

@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)); 
} 

Twierdzenie o id działa prawidłowo, przez typ nie jako a1.getType() jest null. Czy istnieje sposób, aby tego uniknąć? Próbowałem Comparator.nullsLast(...), ale to nie ma sensu, ponieważ nie sortuję tutaj elementów.

Mam wiele zapewnień do zrobienia, więc wolałbym "jedno-liniowy". Jestem nowy w wyrażeniach lambda.

+0

Dlaczego nie chcesz używać 'metody equals'? – ByeBye

+0

Nie mogę zmienić implementacji _Agent_ i nie ma parametru hashCode/equals. – JaneDoe

+0

Co jest nie tak z 'nullsLast'? – immibis

Odpowiedz

12

Jeśli chcesz użyć tego w teście JUnit, dlaczego po prostu nie przekazujesz obiektów, które chcesz porównać bezpośrednio do metody assertEquals?

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

Pomaga to również JUnit wygenerować użyteczny komunikat o błędzie, gdy test się nie powiedzie.

Jeśli chcesz to zrobić w kodzie produkcji, można użyć Objects.equals:

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

która jest obecna od Java 7.

10

coś takiego:

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

Ponieważ trzeba to być wykorzystane w wielu miejscach można wyodrębnić je jako:

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; 
} 
5

Można użyć Objects.equals:

assertEquals("Agent.getId", true, 
    Objects.equals(a1.getID(),a2.getID()); 

assertEquals("Agent.getType", true, 
    Objects.equals(a1.getType(),a2.getType()); 

Objects.equals s obsługuje dla ciebie null.

+0

ah! racja, moja zła – Eugene