简体   繁体   English

Java8中带有流的嵌套列表

[英]Nested lists with streams in Java8

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

You can use two flatMap then a filter then 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);

You can do it with flatMap . 你可以用flatMap来做。

I made an example with Company which 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] [Jon Skeet,Linus Torvalds,Dennis Ritchie,Bjarne Stroustrup,James Gosling,Patrick Naughton]

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

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: init元素集合:

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. 希望它会帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM