Java .removeIf()与.filter().collect()的比较

Java .removeIf()与.filter().collect()的比较,java,java-8,java-stream,Java,Java 8,Java Stream,我需要一个方法,它通过检查元素的字段是否包含在另一个集合的元素字段中来筛选出集合。哪种方式更好: 返回筛选集合的方法: List method1(List foo, List bar){ if(bar.isEmpty()) return Collections.emptyList(); Set<Integer> ids = bar.stream().map(elem->elem.getId).collect(Collectors.toSet()

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

返回筛选集合的方法:

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));
}
列表方法1(列表foo、列表栏){
if(bar.isEmpty())
返回集合。emptyList();
Set id=bar.stream().map(elem->elem.getId).collect(Collectors.toSet());
返回foo.stream().filter(elem->ids.contains(elem.barId));
}
  • 易于处理空条件集合
  • 创建流和另一个集合
或修改原始集合的方法:

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));
}
void方法2(列表foo、列表栏){
if(bar.isEmpty()){
foo.clear();
返回;
}
Set id=bar.stream().map(elem->elem.getId).collect(Collectors.toSet());
foo.removeIf(elem->ids.contains(elem.barId));
}
  • 没有多余的对象
  • 清除原始集合而不是仅返回新集合

返回不同版本输入而不是修改输入的方法是按值传递输入的方法,这是一种符合Java设计方式的策略。 另一种方法是通过引用传递输入的方法,即C的工作方式。正如您刚才证明的,在Java中也可以做到这一点,但这与其说是一个特性,不如说是一个“变通方法”

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


希望我能帮上忙。

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

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

列表方法1(列表foo、列表栏){
if(bar.isEmpty())
返回集合。emptyList();
最终设置barIds=getIds(bar);
返回foo.stream()
.filter(elem->barId.contains(elem.barId))
.collect(Collectors.toList());
}
私有集合getID(最终列表栏){
返回bar.stream()
.map(elem->elem.getId)
.collect(收集器.toSet());
}

请粘贴至少可编译的代码。你的,不是。至少第一个问题是多个问题。好吧,第二个也不是更好。这取决于你是否仍然需要原始的
列表,因为
removeIf
会修改它。就个人而言,我总是使用过滤的
,因为通常你不知道该列表引用的其他位置。使用流会使列表加倍,是吗?那不是真的。流的全部意义在于,它们呈现了一个集合的视图。并没有“加倍”,我认为在这些文本片段和不可编译的代码中可能隐藏着一个值得向上投票的问题……顺便说一句:对于这一点,已经有了特殊的方法,以防你们的两个列表都有相同类型的对象并且行为正确。