如何避免lambda比较器中的NullPointerExceptions?

Jan*_*Doe 12 java comparison lambda nullpointerexception java-8

我想比较两个在运行时可能为null的给定对象.在我的例子中:

@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));
}
Run Code Online (Sandbox Code Playgroud)

id的断言工作正常,按类型不是a1.getType()null.有办法避免这种情况吗?我尝试过Comparator.nullsLast(...),但这没有任何意义,因为我没有在这里排序元素.

我有很多断言要做,所以我更喜欢"单行".我是lambda表达式的新手.

Hoo*_*pje 12

如果您只想在JUnit测试中使用它,为什么不直接将要比较的对象传递给assertEquals方法?

assertEquals("Agent.getId", a1.getId(), a2.getId());
Run Code Online (Sandbox Code Playgroud)

这也有助于JUnit在测试失败时生成有用的错误消息.

如果要在生产代码中执行此操作,可以使用Objects.equals:

if (Objects.equals(a1.getId(), a2.getId())) { ... }
Run Code Online (Sandbox Code Playgroud)

自Java 7以来就存在.


Eug*_*ene 10

像这样的东西:

Comparator.comparing(Agent::getType, 
    Comparator.nullsLast(Comparator.naturalOrder()))
Run Code Online (Sandbox Code Playgroud)

由于您需要在更多地方使用它,您可以将其提取为:

    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;
}
Run Code Online (Sandbox Code Playgroud)


Era*_*ran 5

你可以使用Objects.equals:

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

assertEquals("Agent.getType", true,
    Objects.equals(a1.getType(),a2.getType());
Run Code Online (Sandbox Code Playgroud)

Objects.equalsnull为你处理.