使用 Streams 根据 Java 中最内层列表中的元素从包含其他对象的 3 维对象列表中过滤

Filtering from a 3-dimensional List of Objects containing other objects based on the elements from innermost List in Java using Streams

假设我们有一个 3 维对象列表。

  class Custom {
    int id;
    List<String> list;
    Custom(id, list) { // Constructor }
    // Getters and Setters
  }

  class CustomContainer {
    int id;
    List<Custom> list;
    CustomContainer(id, list) { // Constructor }
    // Getters and Setters
  }

  var l1 = List.of("abc", "def", "acd");
  var l2 = List.of("bed", "fed", "aed");
  var c1 = new Custom(1, l1);
  var c2 = new Custom(2, l2);
  var l3 = List.of(c1, c2);
  var l4 = List.of(c2);
  var cc1 = new CustomContainer(3, l3)
  var cc2 = new CustomContainer(4, l4)
  var containers = List.of(cc1, cc2);

说我想过滤“容器”,这样我想从最里面的列表中删除以“a”开头的所有元素。 因此,输出应该是(考虑到 toString() 仅打印列表中的字符串):

[[["def"],["bed", "fed"]], [["bed", "fed"]]]

如何在 Java 中使用 Streams 获取此内容?

由于您需要处理最内层的集合,但又想收集最外层的元素,因此您需要处理 CustomContainerList,然后为每个元素的列表调用 foreach(收集方法不是流方法)和removeIf

List<CustomContainer> res = containers.stream()
                .peek(container -> container.getList().forEach(custom -> custom.getList().removeIf(str -> str.startsWith("a"))))
                .collect(Collectors.toList());

在测试您的代码时,我还注意到这些子列表是使用 List.of 创建的,其中 returns 和不可变列表,任何修改此类集合的尝试都会抛出 UnsupportedException。如果它们符合您的实际代码,您可能希望像这样编写它们:

        var l1 = new ArrayList(List.of("abc", "def", "acd")); //Conversion constructor
        var l2 = new ArrayList(List.of("bed", "fed", "aed")); //Conversion constructor
        var c1 = new Custom(1, l1);
        var c2 = new Custom(2, l2);
        var l3 = new ArrayList(List.of(c1, c2)); //Conversion constructor
        var l4 = new ArrayList(List.of(c2)); //Conversion constructor
        var cc1 = new CustomContainer(3, l3);
        var cc2 = new CustomContainer(4, l4);
        var containers = new ArrayList<>(List.of(cc1, cc2)); //Conversion constructor

通过使用转换构造函数,您基本上是在批量操作中添加从不可变 list 到可变 ArrayList 的所有元素。