使用流删除深度元素

Remove in depth elements using streams

我有以下类。

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 {}

我想做的是删除 list d 如果特定搜索词不在列表中。我试过但没有运气。我认为它删除了但未保存引用。

a.stream()
        .flatMap(a-> a.getB().stream())
        .flatMap(b-> b.getC().stream())
        .map(c-> c.getD())
        .collect(Collectors.toList())
        .removeIf(list -> {
            boolean toBeRemoved = true;
            boolean containsMatch = list.stream().anyMatch(w-> {return w.getId().equalsIgnoreCase(searchTerm);});
            if(containsMatch) {
                toBeRemoved = false;
            }               
            return toBeRemoved;
        });

有人可以帮助我吗?

流表示 "underlying" 集合中的 视图。这意味着当您在 流上调用 removeIf() 时,"underlying" 集合根本不受影响。

你需要做两件事:首先你 "collect" 你打算删除的所有项目,然后你只需从需要更改的列表中删除它们(在显式调用中):

List<B> toBeDeleted = a.stream()....collect(Collectors.toList());
a.b.removeAll(toBeDeleted);

(以上是伪代码,我没有运行编译过)

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

您所做的构建了一个 List<List<D>>,您删除了 List<D> 个不对应的元素,但不会改变您拥有的对象。

  • 您需要遍历所有 C 个元素,
  • 你保留那些不对应的(使用noneMatch()来检查)
  • 对于这些,您将 list 替换为空的(或清除实际的 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(new ArrayList<>()));    // or .forEach(c-> c.getD().clear());