Java 使用流删除深度元素

Java 使用流删除深度元素,java,java-8,java-stream,remove-if,Java,Java 8,Java Stream,Remove If,我有以下课程 Class A { List<B> b //getters and setters } CLass B { List<C> c //getters and setters } Class C { List<D> d //getters and setter } Class D {} 有人能帮我吗?流表示“基础”集合的视图。这意味着在流上调用removeIf()时,“底层”集合根本不受影响 您需要做

我有以下课程

Class A {
    List<B> b
   //getters and setters
}

CLass B {
   List<C> c
   //getters and setters
}

 Class C {
    List<D> d
   //getters and setter
}

Class D {}

有人能帮我吗?

流表示“基础”集合的视图。这意味着在流上调用
removeIf()
时,“底层”集合根本不受影响

您需要做两件事:首先“收集”所有要删除的项目,然后(通过显式调用)从需要更改的列表中删除它们:

List<B> toBeDeleted = a.stream()....collect(Collectors.toList());
a.b.removeAll(toBeDeleted);
List toBeDeleted=a.stream()…collect(Collectors.toList());
a、 b.移除所有(待删除);
(以上是伪代码,我没有通过编译器运行)


如前所述:这里真正的问题是您的误解:流上的操作通常不会影响底层集合

您所做的构建了一个
列表
,并且删除了不相关的
列表
元素,但这些元素永远不会改变您拥有的对象

  • 您需要迭代所有
    C
    元素
  • 您保留了不对应的项(使用
    noneMatch()
    检查此项)
  • 对于这些选项,您可以将
    列表
    替换为空列表(或清除实际的
    c.getD().clear()
a.stream()
.flatMap(a->a.getB().stream())
.flatMap(b->b.getC().stream())
.filter(c->c.getD().stream().noneMatch(w->w.getId().equalsIgnoreCase(searchTerm)))
.forEach(c->c.setD(新的ArrayList());//或.forEach(c->c.getD().clear());

请澄清:您想从流中删除元素,还是从真实列表中删除元素?!因为后者不可能以这种方式实现。对
a
流的操作不会改变
a
本身!从真正的名单。这里的真实列表是ListSo类型的“a”,对象“c”将有一个空列表?如果在其列表中找到搜索项?是的,完全正确。只是一个旁注,而不是
boolean toBeRemoved=true;布尔containsMatch=someExpression;如果(containsMatch){toBeRemoved=false;}返回toBeRemoved
,您只需编写
返回!某些表达将这一点与以下事实结合起来:您可以编写
参数->{return expression;}
,而不是
参数->表达式
…尽管只是一个旁注,但几乎是完美的答案。“这意味着在流上调用removeIf()时”。流没有
removeIf
方法,而
removeIf
属于任何类型的
集合
。“流上的操作通常不会影响基础集合。”。尽管对于这种特定情况可能是这样,但流元素并不总是存储在底层集合中,因为有时它们可能是根据需要生成的。
List<B> toBeDeleted = a.stream()....collect(Collectors.toList());
a.b.removeAll(toBeDeleted);
a.stream()
    .flatMap(a-> a.getB().stream())
    .flatMap(b-> b.getC().stream())
    .filter(c -> c.getD().stream().noneMatch(w -> w.getId().equalsIgnoreCase(searchTerm)))
    .forEach(c-> c.setD(new ArrayList<>()));    // or .forEach(c-> c.getD().clear());