当列表中包含空值时,如何使用流获取日期列表的最大值

Bar*_*tek 4 java list comparator java-8 java-stream

我有以下代码:

List<LocalDate> dates = Arrays.asList(null, null, 
    LocalDate.now(), LocalDate.now().minusDays(9));

LocalDate max = dates.stream()
    .max(Comparator.nullsLast(Comparator.naturalOrder())).get();
Run Code Online (Sandbox Code Playgroud)

当我尝试获取最大值时会产生空指针异常,但是当尝试获取最小值时会正常工作。这似乎不明原因max发生Comparator该处理空值。如何使用保留空值的流对此类数组进行排序。

顺便说一句,我检查了的JavaDoc max,它指出:

如果最大元素为null,则@throws NullPointerException

编辑:

LocalDate max = dates.stream()
    .max(Comparator.nullsLast(Comparator.naturalOrder())).orElse(null);
Run Code Online (Sandbox Code Playgroud)

也会抛出空指针。

Pet*_*rey 5

如果您希望答案是null因为它包含一个答案,则可以自己进行归类。

List<LocalDate> dates = Arrays.asList(null, null,
        LocalDate.now(), LocalDate.now().minusDays(9));

LocalDate max = dates.stream()
        .reduce(LocalDate.MIN,
                BinaryOperator.maxBy(Comparator.nullsLast(Comparator.naturalOrder())));
System.out.println(max);
Run Code Online (Sandbox Code Playgroud)

版画

null
Run Code Online (Sandbox Code Playgroud)

注意:从空列表返回LocalDate.MIN的意义上来说这是不同的。

一个不太明显的选择是nullLocalDate.MAX假设从未使用过的替换。

LocalDate max = dates.stream()
        .map(d -> d == null ? LocalDate.MAX : d)
        .max(Comparator.naturalOrder())
        .map(d -> LocalDate.MAX.equals(d) ? null : d)
        .orElse(null);
Run Code Online (Sandbox Code Playgroud)

这将返回null一个空列表。

  • 非常好!以前不知道LocalDate.MIN,我希望我以前知道它-可以赢得一对夫妇或争论:) (3认同)
  • @Eugene 虽然 MIN 是一个很大的负面日期,但在 1750 年代之前的任何事情都可能令人担忧。例如,罗马数字中没有 0,儒略历中没有 0 年。 (2认同)