当前位置: 首页 > 知识库问答 >
问题:

使用流过滤java中的内部和外部列表

夹谷鸿福
2023-03-14

有没有一种方法可以使用一些谓词和java流来过滤内部和外部列表?例如:

Class outerObject{
    int num;
    List<innerObject> innerObjectList;
}
Class innerObject{
    int num;
}
List <outerObject> outerObjectList

是否有一种方法可以过滤列表,使得outerObject列表具有字段num=10,并且相应的outerObjectinnerObject列表也会被相应的字段num=10过滤?

我试过:

outerObjectList.stream()
               .filter(i -> i.getNum() == 10)
               .filter(i -> i.getOrders().stream().anyMatch(s -> getNum() == 10))
               .collect(Collectors.toList());

但它似乎无法过滤内部列表。

描述性示例:

如果一个外部列表有3个具有num=10的对象,并且3个对象中的每一个都有1个内部对象在它们的innerObjectList中具有num=10,那么它应该给我一个包含3个outerObject< /code>的列表,每个列表包含1个innerObject


共有3个答案

龚联
2023-03-14

当你在流的上下文中说“filter”时,通常意味着过滤流,以便下游操作看到流的子集。我想你真正想要的是根据条件从列表中删除项目。您可以使用“窥视”操作来完成此操作:

public class Outer {

    private final int num;
    private final List<Inner> inners = new ArrayList<>();

    public class Inner {

        private final int num;

        public Inner(int num) {
            this.num = num;
        }

        public boolean hasNum(int num) {
            return this.num == num;
        }
    }

    public Outer(int num) {
        this.num = num;
    }

    public void addInner(int num) {
        inners.add(new Inner(num));
    }

    public void removeInners(int num) {
        inners.removeIf(i -> i.hasNum(num));
    }

    public boolean hasInner(int num) {
        return inners.stream().anyMatch(i -> i.hasNum(num));
    }

    public boolean hasNum(int num) {
        return this.num == num;
    }
}

@Test
public void testOuter() {
    List<Outer> outers = new ArrayList<>();
    outers.add(new Outer(1));
    outers.add(new Outer(1));
    outers.get(1).addInner(5);
    outers.get(1).addInner(1);
    outers.add(new Outer(2));
    outers.add(new Outer(1));
    outers.get(3).addInner(1);
    outers = outers.stream()
            .filter(o -> o.hasNum(1))
            .peek(o -> o.removeInners(1))
            .collect(Collectors.toList());
    assertThat(outers.size(), is(2));
    assertFalse(outer.stream().anyMatch(i -> i.hasInner(1)));
}

请注意,我将在收集列表后将其分配回变量。

胡元忠
2023-03-14

如果要修改现有列表(而不是创建新列表),可以使用Collection。移除方法:

outerObjectList.removeIf(i -> i.getNum() != 10);
outerObjectList.forEach(i -> i.getOrders().removeIf(s -> s.getNum() != 10));

此操作不需要流API。

周睿范
2023-03-14

它没有过滤内部列表,因为在任何时候都不会更改任何元素;你只是从顶级列表中删除它们。

为了过滤内部列表,您应该有一个. map操作来操作外部对象,将它们更改为新的外部对象,其内部对象列表本身就是旧列表的过滤版本。

outerObjectList.stream()
                .filter(i -> i.getNum() == 10)
              .filter(i -> i.getOrders().stream().anyMatch(s -> getNum() == 10))
                .collect(Collectors.toList());

让我们把它分解一下:你有两条溪流,外部流(在其上调用.filter.filter.collect)和内部流(在其上调用.anyMatch)。最终得到的只是外部流的集合,并且在任何时候都不能修改其任何成员(仅通过删除它们来修改流本身的结构)你根本不修改内部流;您只需报告它的一个特性(“它是否具有getNum()==10?”)

如果你想过滤内部流,你有更多的工作要做。实际上,您可以使用修改外部流的元素。peek,将其列表更改为“过滤”版本;或者,如果你想保持良好和不变,你可以用创建新的过滤版本。地图

对于。map()approach,你需要一个lambda来创建一个新的OuterObject,这样:

  • 输出。num==输入。num
  • 输出。innerObjectList==输入。innerObjectList。stream()。过滤器-

这有意义吗?

 类似资料:
  • 我试图理解Java的流API的内部调用。 我有下面的代码,它有两个过滤器(中间)操作和一个终端操作。 我看到,对于每个中间操作,都会返回一个新流,并使用重写的方法。一旦它命中terminal方法,流就执行。如果有两个操作,我看到正在运行两次,而不是一次。 我想了解一个流遍历如何能够调用过滤器两次。 粘贴下面的IntPipeline代码,在Stream中为filter方法命中该代码。

  • 问题内容: 虽然这两个给我相同的结果,但在内部或外部安装过滤器有什么区别?在表现或幕后动作方面是否有所不同? 问题答案: 在查询中过滤 Elasticsearch将以更有效的方式执行查询和过滤,以减少结果集并尽快获得答案。这称为filtered_query 查询后过滤 首先运行查询, 然后对 结果进行过滤, 然后 再将其返回给客户端。这称为post_filter。 尽管post_filter的效率

  • 我正在寻找一种方法,在一个微服务中有一个用于公共访问的应用编程接口,另一个用于其他私有服务的内部应用编程接口。 当然,这在不同的URL中是可能的。但看起来好像合并了swagger/open api描述页面。 公共和私有API应该有一个单独的招摇页面。来自互联网的人不能看到内部API描述。只有公共的。 有想法吗?

  • 我刚刚开始学习React和JavaScript。在我阅读了留档和教程之后,我看了一下示例项目,并试图整理我还没有得到的内容。 然后我看到有一些函数是在函数内部定义的,还有一些函数是在函数外部定义的。 例如,在之外: 和内部render()。。。 为什么它们看起来如此不同,为什么你想在内部和外部有一些函数? 编辑: 之外的函数的另一个示例: EDIT2:在另一个线程中,有人回答说,如果函数背后的逻辑

  • 考虑我有以下代码 我想做的是我有一个映射,它的值是字符串列表。 这些值将被转换成整数,并将被检查,如果该值大于给定的值,如第二/内过滤器。 我可以把它分成几个小部分,因为我使用了两个过滤器,但从内部过滤器我无法得到布尔值,所以我将得到所需的流,然后使用flatmat(Collection::stream)合并,然后将其转换为set(以避免重复),因为这两个列表都包含一个公共值,即4 我需要的输出必

  • 我刚刚升级到Elastic Search 1.5.0,到目前为止,我无法使inner_hits与嵌套过滤器一起工作,尽管它可以与嵌套查询一起工作。 假设我想检索电影对象中的内部嵌套对象演员。 当我运行以下嵌套查询时: 语法 1 = 但是当我尝试使用嵌套过滤器进行等效查询时: 语法 2 = QueryParsingException[[my_index][nested]需要“查询”或“过滤器”字段]