2017-03-08 65 views
2

我有以下一般形式,其中this.words是含有每個元素一個字一個List<String>的幾類:如何(動態)更改Java流的過濾條件?

public ArrayList<String> wordsInclZ() { 
    ArrayList<String> results = new ArrayList<>(); 

    this.words.stream() 
     .filter(word -> word.contains("z")) 
     .forEach(word -> results.add(word)); 

    return results; 
} 

我必須要改變的唯一位是過濾條件,即,內部.filter()表達。這似乎不是一個可怕的複製粘貼的情況,但我想知道是否有可能編寫更整潔的代碼。

是否有簡明的方式來概括此功能?我想我基本上是問我可以和我應該如何將lambda傳遞給.filter()作爲處理上述方法的其餘功能的一般方法的參數。

+3

此外:您可以使用.collect(Collectors.toList());而不是forEach。然後返回收集的結果。無需定義空的結果列表(爲您的功能) –

回答

3

你可以爲你的函數創建一個參數:

Predicate<String> predicate 

您可以過濾,然後傳遞給你的函數:

wordsInclZ(word -> word.contains("z")); 

和過濾器將是:

filter(predicate); 
+0

謝謝,這是一個完美的解決方案!以下是我最終的結果,以防有人可以使用它:'return this.words.stream()。filter(predicate).collect(Collectors.toCollection(ArrayList :: new));' – basse

1

您可以創建一個函數並將其作爲參數傳遞給過濾器:

public ArrayList<String> wordsInclZ() { 
    ArrayList<String> results = new ArrayList<>(); 

    this.words.stream() 
     .filter(MyClass::myFilterFunction) 
     .forEach(word -> results.add(word)); 

    return results; 
} 

private static boolean myFilterFunction(String word){ 
    // do whatever you need and return TRUE or FALSE 
} 
2

有兩個選項這裏:

  1. 傳遞的方法參照接受一個實際值,並返回一個boolean結果的方法:

    public boolean filter1(String s) { 
        return s.contains("z"); 
    } 
    // .filter(this::filter1) 
    
  2. 返回一個Predicate從方法:

    public Predicate<String> filter2() { 
        return s -> s.contains("z"); 
    } 
    // .filter(filter2())