【问题标题】:.removeIf() vs .filter().collect().removeIf() 与 .filter().collect()
【发布时间】:2020-11-06 16:48:14
【问题描述】:

我需要一个方法,通过检查元素的字段是否包含在另一个集合的元素字段中来过滤出集合。哪种方式更好:

一个方法,返回过滤后的集合:

List method1(List foo, List bar){
    if(bar.isEmpty()) 
        return Collections.emptyList();
    Set<Integer> ids = bar.stream().map(elem->elem.getId).collect(Collectors.toSet());
    return foo.stream().filter(elem->ids.contains(elem.barId));
}
  • 轻松处理空条件集合
  • 创建流和另一个集合

或者一个方法,修改原来的集合:

void method2(List foo, List bar){
    if(bar.isEmpty()){ 
         foo.clear();
         return;
    }
    Set<Integer> ids = bar.stream().map(elem->elem.getId).collect(Collectors.toSet());
    foo.removeIf(elem->ids.contains(elem.barId));
}
  • 没有多余的对象
  • 清除原始集合而不是仅返回新集合

【问题讨论】:

  • 请粘贴至少可以编译的代码。你的,没有。至少第一个是多个问题。那么第二个不是更好。
  • 这取决于你是否还需要原来的List,因为removeIf 修改了它。就个人而言,我总是使用过滤后的Stream,因为通常您不知道该列表还引用了哪些其他地方。
  • 使用流加倍列表 嗯?那不是真的。流的全部意义在于它们在集合上呈现视图。没有“加倍”
  • 我认为可能在这些文本片段和不可编译的代码中隐藏着一个值得投票的问题......
  • 顺便说一句:这个boolean retainAll(Collection<?> c) 已经有特殊的方法,以防您的两个列表具有相同类型的对象并且equals 行为正确。

标签: java java-8 java-stream


【解决方案1】:

第一种方法更好。现实生活中的out参数概念很难维护。

【讨论】:

    【解决方案2】:

    您的method1method2 将无法按预期工作,因为它在foo 上的最后一个流中没有终端操作。建议尽可能使用不可变的方法,因为它导致代码不易出错并且易于理解代码行为。 You should read about this

    List method1(List foo, List bar){
        
        if (bar.isEmpty()) 
            return Collections.emptyList();
    
        final Set<Integer> barIds = getIds(bar);
        return foo.stream()
                  .filter(elem->barIds.contains(elem.barId))
                  .collect(Collectors.toList());
    }
    
    private Set<Integer> getIds(final List bar) {
    
      return bar.stream()
                .map(elem->elem.getId)
                .collect(Collectors.toSet());
    }
    

    【讨论】:

      【解决方案3】:

      返回输入的不同版本而不是修改输入的方法是按值传递输入的方法,这是一种符合 Java 设计方式的策略。 另一种方法是通过引用传递输入的方法,C 的工作方式。正如您刚刚证明的那样,在 Java 中也可以做到这一点,但这更像是一种“解决方法”而不是一种特性。 (More info on this)

      没有告诉你哪个版本更好,但如果有疑问,我会使用第一个。

      希望我能帮上忙。

      【讨论】:

        猜你喜欢
        • 2020-06-30
        • 2019-06-22
        • 1970-01-01
        • 2016-10-26
        • 2017-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多