如何在Java 8中平铺列表

4
class Employee {
    private String name;
    private List<Employee> members;
}

List<Employee> emps = Arrays.asList(new Employee("A", Arrays.asList(
     new Employee("B", null),
     new Employee("C", null)
)))

代码用于将List展开:
List<Employee> total = 
    emps.stream()
        .flatMap(emp -> emp.members.stream())
        .collect(Collectors.toList());

总的List应该有3个元素,但它只有2个。


那种类型看起来更像一棵树而不是一个列表...或者是列表的列表。 - Stephen C
3个回答

6
Eran 的回答是错误的,Stream 实例上没有 concat 方法。应该使用以下代码:
emps.stream()
        .flatMap(emp -> Stream.concat(emp.members.stream(), Stream.of(emp)))
        .collect(Collectors.toList());

Stream#concat


2
替代方案是:
List<Employee> total = emps.stream()
                      .collect(ArrayList::new,
                               (l, e) -> {l.add(e);l.addAll(e.getMembers());},
                               List::addAll);

1
你的流水线只返回被其他Employee引用的Employee。它不保留外部输入List中的Employee
要获取所有Employee,可以将你的flatMap更改为将当前Employee与其引用的Employee连接起来。
List<Employee> total = 
    emps.stream()
        .flatMap(emp -> Stream.concat(emp.members.stream(),Stream.of(emp)))
        .collect(Collectors.toList());

或者(如果您更喜欢外部的Employee在相应的引用Employee之前出现):
List<Employee> total = 
    emps.stream()
        .flatMap(emp -> Stream.concat(Stream.of(emp),emp.members.stream()))
        .collect(Collectors.toList());

请注意,结果可能包含重复项。您可以通过在flatMap()后添加distinct()来消除它们(假设您的Employee类覆盖了equals()hashCode())。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接