2017-10-04 28 views
2

整數的排序名單比方說你有一個包含空vaues的Java 8 - 用null

List<Integer> integers = Arrays.asList(null, 9, 11, 7, 5, null); 

現在,如果你想獲得最大的價值整數的列表,你可以嘗試

OptionalInt max = integers.stream() 
     .mapToInt(Integer::valueOf) 
     .max(); 

這如果列表中不包含空值,則可以工作。在我們的例子中會有一個NullPointerException。經過一番研究,我可以看到這樣的解決方案

Optional<Integer> max = integers.stream() 
     .max(Comparator.nullsFirst(Comparator.naturalOrder())); 

它的工作原理,如果你認爲零值小於非零。但是,如果你想他們是更大的,改變nullsFirst到nullsLast

Optional<Integer> max = integers.stream() 
     .max(Comparator.nullsLast(Comparator.naturalOrder())); 

,那麼你還會再見面的NullPointerException。

我很有趣 - 爲什麼nullsLast在這種情況下不起作用,因爲它的文檔聲明它是無效的? 什麼是排序包含空值的整數列表的最佳方法?

感謝您的想法!

回答

2

Stream#max狀態的文檔:

拋出:NullPointerException - 如果最大的元素爲null

正如你提供一個比較,將考慮null作爲最大的元素,那麼這就是爲什麼它會拋出異常。

這是堆棧跟蹤表明,當它試圖與state在你的例子是null返回Optional.of(state);,並Optional.of拋出一個NPE,如果傳遞的值是null

Comparator.nullsLast正常工作,例如:

Integer max = 
    Collections.max(integers, Comparator.nullsLast(Comparator.naturalOrder())); 

確實會給你null

0

這不是Comparator每本身:

List<Integer> result = integers.stream() 
      .sorted(Comparator.nullsLast(Comparator.naturalOrder())) 
      .collect(Collectors.toList()); 
System.out.println(result); // [5, 7, 9, 11, null, null] 

你把你的零點到最後,這將是max;在空的情況下調用max會引發NullPointerException

2

如果考慮null比任何非null值越大,最高會,當然,null當列表中包含的任何null

由於Stream.max已經有文件說明,當結果爲null時,它會拋出NullPointerException,這是預期的行爲。設計原理類似於findFirst(),其已在this Q&A中討論過。

注意,即使

Optional<Integer> max = integers.stream() 
    .max(Comparator.nullsFirst(Comparator.naturalOrder())); 

仍然可能失敗,即如果所有值都null。但在使用自定義Comparator在這裏,因爲該解決方案沒有點直接:

OptionalInt max = integers.stream() 
    .filter(Objects::nonNull) 
    .mapToInt(Integer::valueOf) 
    .max(); 

當你得到一個空OptionalInt,你還可以測試integers.isEmpty()確定所有要素是否null或沒有元素。