【问题标题】:How to (dynamically) change Java stream's filter conditions?如何(动态)更改 Java 流的过滤条件?
【发布时间】:2017-03-08 08:24:24
【问题描述】:

我有以下一般形式的几个类,其中this.wordsList<String>,每个元素包含一个单词:

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()

【问题讨论】:

  • 另外:您可以使用 .collect(Collectors.toList());而不是 forEach。然后返回收集的结果。无需定义空结果列表。(为您的功能)

标签: java lambda java-8 java-stream predicate


【解决方案1】:

你可以为你的函数创建一个参数:

Predicate<String> predicate

然后您可以将过滤器传递给您的函数:

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

过滤器是:

filter(predicate);

【讨论】:

  • 谢谢,这是完美的解决方案!这是我最终得到的,以防有人可以使用它:return this.words.stream().filter(predicate).collect(Collectors.toCollection(ArrayList::new));
  • 不要大惊小怪,但可以通过将最终收集更改为 collect(Collectors.toList()) 来减少一些字符。
【解决方案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())
    

【讨论】:

    【解决方案3】:

    您可以创建一个函数并将其作为参数传递给过滤器:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-13
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 1970-01-01
      相关资源
      最近更新 更多