Как избежать NullPointerExceptions в лямбда-компараторах?
Я хочу сравнить два заданных объекта, которые могут быть пустыми во время выполнения. В моем примере:
@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));
}
Утверждение id работает нормально, по типу не как a1.getType()
равно null. Есть ли способ избежать этого? Я пробовал Comparator.nullsLast(...)
, но это не имеет смысла, поскольку я не сортирую элементы здесь.
У меня есть много утверждений, поэтому я бы предпочел "однострочный" . Я новичок в лямбда-выражениях.
Ответы
Ответ 1
Если вы просто хотите использовать это в тесте JUnit, почему бы вам просто не передать объекты, которые хотите сравнить непосредственно с методом assertEquals
?
assertEquals("Agent.getId", a1.getId(), a2.getId());
Это также помогает JUnit генерировать полезное сообщение об ошибке при неудаче теста.
Если вы хотите сделать это в производственном коде, вы можете использовать Objects.equals
:
if (Objects.equals(a1.getId(), a2.getId())) { ... }
который присутствует с Java 7.
Ответ 2
Что-то вроде этого:
Comparator.comparing(Agent::getType,
Comparator.nullsLast(Comparator.naturalOrder()))
Поскольку вам нужно, чтобы это использовалось в других местах, вы можете извлечь его как:
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;
}
Ответ 3
Вы можете использовать Objects.equals
:
assertEquals("Agent.getId", true,
Objects.equals(a1.getID(),a2.getID());
assertEquals("Agent.getType", true,
Objects.equals(a1.getType(),a2.getType());
Objects.equals
обрабатывает null
для вас.