簡體   English   中英

使用java 8流處理null屬性並使用lambda表達式進行排序

[英]Dealing with a null attribute using java 8 streams and sorting using lambda expressions

讓我們考慮一個只包含一個Integer屬性的Parent類。 我創建了6個父類對象,屬性值為100, 20, 300, 400, 500, null

現在我將所有對象添加到列表中(列表名稱是列表)。 然后我想得到屬性值大於100的對象。 我為此目的使用了Java 8流。

Predicate<Entity> predicate = e -> e.getParentId() < 100;
result = list.stream().filter(predicate).collect(Collectors.toList());

我還想按降序對列表進行排序。 我為此目的使用了以下代碼。

Comparator<Entity> comp = (d1,d2) -> d2.getId().compareTo(d1.getId());
list.sort(comp);

在這兩種情況下,我都會得到一個NullPointerException

怎么辦呢?

這里的所有答案都圍繞着“拋出壞元素,那些具有null getParentId()元素。” 如果它們確實很糟糕,那可能就是答案。 但還有另一種選擇: Comparators.nullsFirst (或last。)這允許您將處理空值的事物比較為小於(或大於)所有非空值,因此您不必將元素拋出null parentId away。

Comparator<Entity> cmp = nullsLast(comparing(Entity::getParentId));
List<Entity> list = list.stream().sorted(cmp).collect(toList());

你可以做類似的過濾; 將您的謂詞定義為:

Predicate<Entity> predicate = e -> e.getParentId() != null 
                                       && e.getParentId() < 100;

看起來你正在尋找類似的東西:

list.sort(Comparator.comparing(Entity::getParent, 
                               Comparator.nullsLast(Integer::compareTo)));

父null的所有元素都將放在末尾,其余元素將按其父級排序。

嘗試僅對非null parentId值進行預過濾:

result = list.stream().filter(e -> e.getParentId() != null).filter(predicate).collect(Collectors.toList());

[編輯]剛看到,屬性( e.parentId )似乎是null 在那種情況下,第二件事,排序,打破。 您正在排序原始列表,而不是已過濾的列表。 嘗試result.sort(comp) ,然后你應該避免使用NPE。

您可以在一個Stream管道中完成所有操作:

List<Entity> result =  
    list.stream()
        .filter(e -> e.getParentId()!=null) // it's not clear if the null
                                            // is the Entity object itself
                                            // (in which case it should be e!=null)
                                            // or just the ParentId member
        .filter(predicate)
        .sorted(comp)
        .collect(Collectors.toList());

順便說一句,根據你的問題的文本,原始謂詞應該是:

Predicate<Entity> predicate = e -> e.getParentId() > 100; // not < 100

利用方法參考的強大功能使代碼更緊湊:

   List<Entity> result =
            list.stream()
                    .filter(Objects::nonNull) 
                    .filter(predicate)
                    .sorted(comp)
                    .collect(Collectors.toList());

你可以做:

Predicate<Entity> predicate = e -> e.getParentId() < 100;
Predicate<Entity> nonNull = e -> e != null;
result = list.stream().filter(nonNull)
                      .filter(predicate)
                      .collect(Collectors.toList());

當然,您可以謂詞合並為一個,但為了更好的可讀性,我引入了第二個謂詞。 此外,您可以自由更改nonNull謂詞以檢查整個實體,或僅檢查id屬性(甚至兩者)。 只是玩一下吧。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM