objects 的扁平树同时保留父亲和 child
Flat tree of objects while keeping father and child
我有一个 class 员工,其树结构为 属性 team
public class Employee {
private String name;
private List<Employee> team;
}
使用 Java lambda 我需要将这棵树平展到同一级别的列表中,同时将 Employee class 转换为以下 ConvertedEmployee,同时将名称存储在专用的 lead
和 subordinates
中特性。因此,ConvertedEmployee 在某种意义上是一个保持 parent 和 children 的节点。我需要一份清单。
public class ConvertedEmployee {
private String name;
private String lead;
private List<String> subordinatesNames;
}
所以最终结果应该是List<ConvertedEmployee>
我想在这里使用递归。
但是我只能把树弄平,不能重建它的parents。
编辑:
输入是 Employee object 的实例,它基本上在 team
中有一棵树
一种非递归解决方案,使用流的串联,然后过滤掉没有设置 lead
字段的“重复”条目:
public static List<ConvertedEmployee> convert(List<Employee> staff) {
return staff
.stream()
.flatMap(e -> Stream.concat(
// subordinates of current employee
e.getTeam()
.stream()
.map(sub -> new ConvertedEmployee(
sub.getName(), e.getName(),
sub.getTeam().stream().map(Employee::getName).collect(Collectors.toList())
)),
// current employee by themself
Stream.of(new ConvertedEmployee(
e.getName(), null,
e.getTeam().stream().map(Employee::getName).collect(Collectors.toList())
))
))
.collect(Collectors.collectingAndThen(
Collectors.toMap(
ConvertedEmployee::getName,
c -> c,
(e1, e2) -> e1.getLead() != null ? e1 : e2.getLead() != null ? e2 : e1,
LinkedHashMap::new
),
map -> new ArrayList<>(map.values())
));
}
测试以下设置:
Employee intern = new Employee("intern", Collections.emptyList());
Employee junior = new Employee("junior", Collections.emptyList());
Employee middleDev = new Employee("mid", Arrays.asList(junior));
Employee devOps = new Employee("devOps", Collections.emptyList());
Employee teamLead = new Employee("teamLead", Arrays.asList(intern, middleDev));
Employee pm = new Employee("mgr", Arrays.asList(teamLead, devOps));
List<Employee> staff = Arrays.asList(intern, junior, middleDev, devOps, teamLead, pm);
convert(staff).forEach(System.out::println);
输出:
ConvertedEmployee(name=intern, lead=teamLead, subordinatesNames=[])
ConvertedEmployee(name=junior, lead=mid, subordinatesNames=[])
ConvertedEmployee(name=mid, lead=teamLead, subordinatesNames=[junior])
ConvertedEmployee(name=devOps, lead=mgr, subordinatesNames=[])
ConvertedEmployee(name=teamLead, lead=mgr, subordinatesNames=[intern, mid])
ConvertedEmployee(name=mgr, lead=null, subordinatesNames=[teamLead, devOps])
我有一个 class 员工,其树结构为 属性 team
public class Employee {
private String name;
private List<Employee> team;
}
使用 Java lambda 我需要将这棵树平展到同一级别的列表中,同时将 Employee class 转换为以下 ConvertedEmployee,同时将名称存储在专用的 lead
和 subordinates
中特性。因此,ConvertedEmployee 在某种意义上是一个保持 parent 和 children 的节点。我需要一份清单。
public class ConvertedEmployee {
private String name;
private String lead;
private List<String> subordinatesNames;
}
所以最终结果应该是List<ConvertedEmployee>
我想在这里使用递归。
但是我只能把树弄平,不能重建它的parents。
编辑:
输入是 Employee object 的实例,它基本上在 team
一种非递归解决方案,使用流的串联,然后过滤掉没有设置 lead
字段的“重复”条目:
public static List<ConvertedEmployee> convert(List<Employee> staff) {
return staff
.stream()
.flatMap(e -> Stream.concat(
// subordinates of current employee
e.getTeam()
.stream()
.map(sub -> new ConvertedEmployee(
sub.getName(), e.getName(),
sub.getTeam().stream().map(Employee::getName).collect(Collectors.toList())
)),
// current employee by themself
Stream.of(new ConvertedEmployee(
e.getName(), null,
e.getTeam().stream().map(Employee::getName).collect(Collectors.toList())
))
))
.collect(Collectors.collectingAndThen(
Collectors.toMap(
ConvertedEmployee::getName,
c -> c,
(e1, e2) -> e1.getLead() != null ? e1 : e2.getLead() != null ? e2 : e1,
LinkedHashMap::new
),
map -> new ArrayList<>(map.values())
));
}
测试以下设置:
Employee intern = new Employee("intern", Collections.emptyList());
Employee junior = new Employee("junior", Collections.emptyList());
Employee middleDev = new Employee("mid", Arrays.asList(junior));
Employee devOps = new Employee("devOps", Collections.emptyList());
Employee teamLead = new Employee("teamLead", Arrays.asList(intern, middleDev));
Employee pm = new Employee("mgr", Arrays.asList(teamLead, devOps));
List<Employee> staff = Arrays.asList(intern, junior, middleDev, devOps, teamLead, pm);
convert(staff).forEach(System.out::println);
输出:
ConvertedEmployee(name=intern, lead=teamLead, subordinatesNames=[])
ConvertedEmployee(name=junior, lead=mid, subordinatesNames=[])
ConvertedEmployee(name=mid, lead=teamLead, subordinatesNames=[junior])
ConvertedEmployee(name=devOps, lead=mgr, subordinatesNames=[])
ConvertedEmployee(name=teamLead, lead=mgr, subordinatesNames=[intern, mid])
ConvertedEmployee(name=mgr, lead=null, subordinatesNames=[teamLead, devOps])