使用Java 8 Stream API过滤嵌套列表

时间:2019-04-22 10:10:16

标签: java java-8 java-stream

我无法以Java 8流格式在代码段下方进行转换。

regressor.coef

我正在将第三级嵌套列表对象与输入字段列表进行比较。如果字段不匹配,那么我将从原始列表中删除它们。 如何使用Java 8语法实现这一目标。

编辑:我希望返回FirstClass列表。

4 个答案:

答案 0 :(得分:3)

在这种情况下,我认为信息流不会给您带来任何好处。您要做的只是遍历嵌套列表,并且增强的for循环或forEach更加简单。

可以使用removeIf来修改列表,也可以通过将拒绝逻辑移出循环来进行改进:

Predicate<ThirdClass> reject = third -> !titles.contains(third.getField());

firstClassList.forEeach(first ->
    first.getSecondClassList().forEach(second ->
        second.getThirdClassList().removeIf(reject)
    )
);

答案 1 :(得分:1)

通过展平SecondClass获得firstClassList对象流,并为每个SecondClass获取ThirdClass对象的过滤列表,并将其放回{{1} }

SecondClass

答案 2 :(得分:1)

首先,您可以使用Stream.map()Stream.flatMap()来获得包含StreamList的{​​{1}}。要删除符合条件的项目,您可以使用Collection.removeIf(),它将从符合给定条件的集合中删除所有项目:

ThirdClass

这将修改原始列表,就像您在示例中所做的一样。然后,您可以使用firstClassList.stream() // Stream<FirstClass> .map(FirstClass::getSecondClassList) // Stream<List<SecondClass>> .flatMap(Collection::stream) // Stream<SecondClass> .map(SecondClass::getThirdClassList) // Stream<List<ThirdClass>> .forEach(thirdList -> thirdList.removeIf(third -> !titles.contains(third.getField()))); 作为结果进行进一步处理。

此外,我建议为您的标题使用Set<String>而不是firstClassList,因为它的时间复杂度为 O(1)而不是 O(n)

List<String>

答案 3 :(得分:0)

假设您数据结构中的三个级别是集合,那么解决方案可能是:

  1. 将结构展平到叶子水平
  2. 按所需标题过滤
final List<ThirdClassList> results = firstClassList
    .stream()
    .flatMap(FirstClassList::getSecondClassList)
    .flatMap(FirstClassList::getThirdClassList)
    .filter(third -> !titles.contains(third))
    .collect(toList());

这将为您提供要删除的叶级对象,尽管这当然只是解决方案的一半,您仍然希望删除它们。

如果您是列表类的作者,那么也许您可以从每个第三级到其“父级”第二级都有一个引用,因此删除是一个相对简单的第二步:

results.forEach(third -> third.parent().remove(this));

其中third.parent()返回第二级对象。