簡體   English   中英

分層過濾使用 Java Stream API

[英]Layered filtering using Java Stream API

我有一些命令式 Java 條件代碼,我想重構以使用 Streams。

具體來說,我有這個 map,我想根據特定的過濾條件過濾到一個列表中。

private  Map<Integer,Thing> thingMap = new HashMap<Integer,Thing>();
// populate thingMap

這是使用它的代碼:

List<Thing> things = new ArrayList<Thing>();

for (Thing thing : thingMap.values()) {
    if (thing.getCategory().equals(category)) {
        if (location == null) {
            things.add(thing);
        } else if (thing.getLocation().equals(location)) {
            things.add(thing);
        }
    }
}

我將其重構為以下內容。 但是缺少的是我希望在類別過濾器通過時才檢查位置。 另外,我懷疑有更好的方法來做到這一點:

List<Thing> things = thingMap.entrySet()
                      .stream()
                      .filter(t -> t.getValue().getCategory().equals(category))
                      .filter(t -> 
                          location == null || 
                          t.getValue().getLocation().equals(location)
                       )
                      .map(Map.Entry::getValue)
                      .collect(Collectors.toList());
    

使用 Streams 保留分層條件檢查的慣用方法是什么?

filter之后鏈接的操作只會對謂詞接受的元素執行。 所以沒有必要擔心這一點。

您還可以將條件加入單個filter步驟,就像您可以將嵌套的if語句加入單個if一樣,通過使用&&組合條件。 結果是一樣的。

但請注意,循環使用條件location == null ,指的是在您發布的代碼片段之外聲明的變量,而不是thing.getLocation() == null

除此之外,與循環相比,您還進行了其他不必要的更改。 該循環遍歷 map 的values()視圖,而您將entrySet()用於 Stream,從而需要在Map.Entry上調用getValue()四次。

循環邏輯的直接翻譯要簡單得多:

List<Thing> things = thingMap.values().stream()
    .filter(thing -> thing.getCategory().equals(category))
    .filter(thing -> location == null || thing.getLocation().equals(location))
    .collect(Collectors.toList());

暫無
暫無

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

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