[英]Java recursive parent child hierarchy
class Employee{
private String employeeId;
private boolean isLeaf;
private List<Employee> children;
}
empl
emp2
emp2a
emp2b
emp2b1
emp3
emp3a
..
..
..
使用上述層次結構,我想創建每個員工的孩子。
預期output:獲取每個父母的孩子
Map<String,Set<String>>
{"empl1",["emp2","emp2a","emp2b","emp2b1","emp3","emp3a"]}
{"empl2",["emp2a","emp2b","emp2b1"]}
{"empl2b",["emp2b1"]}
{"emp3",["emp3a"]}
這是否可以使用現有的 Employee class 結構?
試過這個,但不起作用,不知道如何/在哪里停止循環任何幫助都非常感謝。 謝謝!
public void visitAllNodes(Employee emp){
Map<String,Set> childMap = new HashMap<>();
Map<String,Set> finalResult =
visitChildNodesTest(childMap,emp.getEmployeeId(),emp.getEmployees());
}
private Map<String, List> visitChildNodesTest(Map<String, List>
parentChildMap, String parentEmpId,
List<Employee> employees) {
if (CollectionUtils.isNotEmpty(employees)) {
employees.forEach(employee -> {
if (employee.getEmployees() != null) {
getAndPut(parentChildMap,employee.getEmployeeId(),parentEmpId);
visitChildNodesTest(parentChildMap, employee.getEmployeeId(),
employee.getEmployees());
}
});
}
return parentChildMap;
}
private void getAndPut(Map<String, List> parentChildMap, String
employeeId, String parentEmpId) {
if (parentChildMap.get(parentEmpId) == null) {
List<String> ls = new ArrayList<>();
ls.add(parentEmpId);
ls.add(employeeId);
parentChildMap.put(parentEmpId, ls);
} else {
List ls = parentChildMap.get(parentEmpId);
ls.add(employeeId);
parentChildMap.put(parentEmpId, ls);
}
}
我認為解決方案的基礎是這樣的遞歸方法:
public Set<String> getDescendantIds() {
Set<String> result = new HashSet<>();
if (!isLeaf) {
children.forEach(c -> result.add(c.employeeId));
children.forEach(c -> result.addAll(c.getDescendantIds()));
}
return result;
}
嘗試這個。
class Employee {
private String employeeId;
public String getEmployeeId() { return employeeId; }
private boolean isLeaf() { return children.size() == 0; }
private List<Employee> children = new ArrayList<>();
@Override public String toString() { return employeeId; }
public Employee(String employeeId, Employee... children) {
this.employeeId = employeeId;
for (Employee child : children)
this.children.add(child);
}
public Set<Employee> descendants() {
Set<Employee> descendants = new LinkedHashSet<>();
for (Employee child : children) {
descendants.add(child);
descendants.addAll(child.descendants());
}
return descendants;
}
}
和
Employee emp1 =
new Employee("emp1",
new Employee("emp2",
new Employee("emp2a"),
new Employee("emp2b",
new Employee("emp2b1"))),
new Employee("emp3",
new Employee("emp3a")));
Set<Employee> employees = new LinkedHashSet<>();
employees.add(emp1);
employees.addAll(emp1.descendants());
System.out.println(employees);
Map<String, Set<String>> map = employees.stream()
.filter(Predicate.not(Employee::isLeaf))
.collect(Collectors.toMap(Employee::getEmployeeId,
e -> e.descendants()
.stream()
.map(Employee::getEmployeeId)
.collect(Collectors.toSet())));
System.out.println(map);
output
[emp1, emp2, emp2a, emp2b, emp2b1, emp3, emp3a]
{emp3=[emp3a], emp2=[emp2b1, emp2a, emp2b], emp1=[emp2b1, emp3, emp3a, emp2, emp2a, emp2b], emp2b=[emp2b1]}
function 在您的員工 class 中應該這樣做。
public Set<Employee> deepList(){
Set<Employee> result = new HashSet<>();
for(Employee e : children){
result.add(e);
for(Employee c : e.deepList()) result.add(c);
}
return result;
}
這是一個簡短的測試:
import java.util.*;
class Employee{
public static void main(String[] args) {
// only for testing
Employee emp1 = new Employee("emp1");
Employee emp2 = emp1.addChildren(new Employee("emp2"));
emp2.addChildren(new Employee("emp2a"));
Employee emp2b = emp2.addChildren(new Employee("emp2b"));
emp2b.addChildren(new Employee("emp2b1"));
Employee emp3 = emp1.addChildren(new Employee("emp3"));
emp3.addChildren(new Employee("emp3a"));
emp1.deepListTest();
}
private String employeeId;
private boolean isLeaf;
private List<Employee> children = new ArrayList<>();
public Employee(String employeeId) {
this.employeeId = employeeId;
}
public Employee addChildren(Employee employee){
children.add(employee);
return employee;
}
public String getEmployeeId() {
return employeeId;
}
// only for test purposes as a set<String>
public Set<String> deepListTest(){
Set<String> result = new HashSet<>();
for(Employee e : children){
result.add(e.getEmployeeId());
for(String c : e.deepListTest()) result.add(c);
}
if(!children.isEmpty()) System.out.println("{" + employeeId + ", [" + String.join(", ", result) + "]}");
return result;
}
}
結果:
{emp2b, [emp2b1]}
{emp2, [emp2b1, emp2a, emp2b]}
{emp3, [emp3a]}
{emp1, [emp2b1, emp3, emp3a, emp2, emp2a, emp2b]}
我希望這能解決你的問題。
我認為您的代碼看起來不錯,除了只需要刪除“ parentChildMap.put(parentEmpId, ls);
”的最后一行,然后代碼將按您的預期工作,當它通過所有節點時它會自動停止,因為您那里有“isNotEmpty”的條件。
有關為什么需要刪除該行的更多信息,因為List ls = parentChildMap.get(parentEmpId);
已經獲得列表引用,您只需將元素添加到該列表
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.