用于在Java 8 Stream中进行排序的空安全日期比较器

And*_*rew 31 java java-8 java-stream

我用这个来获得最新的项目.我怎样才能使这个为null安全并且最后(最旧)的空日期排序.createDt是一个joda LocalDate对象.

Optional<Item> latestItem = items.stream()
                             .sorted((e1, e2) -> e2.getCreateDt().compareTo(e1.getCreateDt()))
                             .findFirst();
Run Code Online (Sandbox Code Playgroud)

Pau*_*ton 58

如果它Item是可能为null 的s,请使用@ rgettman的解决方案.

如果它LocalDate是可能为null 的s,请使用:

items.stream()
     .sorted(Comparator.comparing(Item::getCreateDt, Comparator.nullsLast(Comparator.reverseOrder())));
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,请注意,sorted().findFirst()由于大多数标准实现首先对整个流进行排序,因此可能效率低下.您应该使用Stream.min.

  • 有没有相反的替代方案?这让我很困惑。 (2认同)
  • @RyanTheLeach:当然,那就是“Comparator.naturalOrder()”。 (2认同)

rge*_*man 14

您可以Comparator通过包装将自己的null-unsafe 转换为null-safe Comparator.nullsLast.(还有一个Comparator.nullsFirst.)

返回一个空值友好的比较器,它被认为null大于非null.当两者都是时null,它们被认为是平等的.如果两者都为非null,Comparator则使用指定的顺序来确定顺序.

.sorted(Comparator.nullsLast(
     (e1, e2) -> e2.getCreateDt().compareTo(e1.getCreateDt())))
.findFirst();
Run Code Online (Sandbox Code Playgroud)

  • 这有助于“e1”或“e2”为 null,但当 getCreatedTt() 返回 null 时则没有帮助 (5认同)
  • @LouisWasserman虽然你当然可以使用`Comparator.comparing`,但我正在寻找解决眼前的问题.无论如何保罗的回答更好,所以我对它进行了投票. (3认同)
  • 当 e2.getCreateDt() == null 时,将抛出 NullPointerException (3认同)