Java8中带有流的嵌套列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51630352/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:11:11  来源:igfitidea点击:

Nested lists with streams in Java8

javalistjava-8java-streamnested-loops

提问by sk555

I have a list of objects A. Each object A in this list contains list of object B and the object B contains list of Object C. The object C contains an attribute name that i want to use to filter using java 8.

我有一个对象 A 的列表。这个列表中的每个对象 A 都包含对象 B 的列表,对象 B 包含对象 C 的列表。对象 C 包含一个属性名称,我想用它来使用 java 8 进行过滤。

how to write the code below in java 8 using streams to avoid nested loop :

如何使用流在 java 8 中编写以下代码以避免嵌套循环:

C c1 = null;
String name = "name1"
for (A a: listOfAObjects) {
    for (B b: a.getList()) {
        for (C c: b.getPr()) {
            if (c.getName().equalsIgnoreCase(name)) {
                c1= c;
                break;
            }
        }
    }
}

采纳答案by YCF_L

You can use two flatMapthen a filterthen you can pick the first one or if no result return null:

您可以使用两个flatMap然后一个filter然后您可以选择第一个或者如果没有结果返回null

C c1 = listOfAObjects.stream()
        .flatMap(a -> a.getList().stream())
        .flatMap(b -> b.getPr().stream())
        .filter(c -> c.getName().equalsIgnoreCase(name))
        .findFirst()
        .orElse(null);

回答by Eugene

 listOfObjectsA.stream()
               .flatMap(a -> a.getListOfObjectsB.stream())
               .flatMap(b -> b.getListOfObjectsC().stream())
               .filter(c -> name.equals(c.getName()))
               .findAny()
               .orElse(....)

回答by Arnaud Denoyelle

You can do it with flatMap.

你可以用flatMap.

I made an example with Companywhich contains a list of Person:

我做了一个例子,Company其中包含一个列表Person

public static void main(String[] args) {
    List<Company> companies = Arrays.asList(
            new Company(Arrays.asList(new Person("Jon Skeet"), new Person("Linus Torvalds"))),
            new Company(Arrays.asList(new Person("Dennis Ritchie"), new Person("Bjarne Stroustrup"))),
            new Company(Arrays.asList(new Person("James Gosling"), new Person("Patrick Naughton")))
    );

    List<String> persons = companies.stream()
            .flatMap(company -> company.getPersons().stream())
            .map(Person::getName)
            .collect(Collectors.toList());

    System.out.println(persons);
}

Output :

输出 :

[Jon Skeet, Linus Torvalds, Dennis Ritchie, Bjarne Stroustrup, James Gosling, Patrick Naughton]

[乔恩·斯基特、莱纳斯·托瓦兹、丹尼斯·里奇、比贾恩·斯特劳斯特鲁普、詹姆斯·高斯林、帕特里克·诺顿]

回答by Alexander Yushko

I had same task but i had one nested class. And I had to filter the objects with filter in the nested collection. As a result, I had to get items that have matches in the collection.

我有同样的任务,但我有一个嵌套类。而且我必须在嵌套集合中使用过滤器过滤对象。因此,我必须获取集合中具有匹配项的项目。

for example:

例如:

public class RootElement {
    private String name;
    private List<String> nestedElements;

    //getters / setters and constructors
}

init collection with elements:

带有元素的初始化集合:

List<RootElement> elements = Arrays.asList(
                new RootElement("first", Arrays.asList("one", "two", "three")),
                new RootElement("second", Arrays.asList("four", "one", "two")));

filter example:

过滤示例:

String filterParam = "four";
        List<RootElement> filtered = elements.stream()
                .flatMap(root -> root.getNestedElements()
                        .stream()
                        .filter(nested -> nested.equalsIgnoreCase(filterParam))
                        .map(filteredElement -> new RootElement(root.getName(), root.getNestedElement())))
                .collect(Collectors.toList());

Hope it will help someone.

希望它会帮助某人。