【问题标题】:Java recursive parent child hierarchyJava递归父子层次结构
【发布时间】:2021-07-04 06:01:54
【问题描述】:
class Employee{
  private String employeeId;
  private boolean isLeaf;
  private List<Employee> children;    
}

empl
   emp2
     emp2a
     emp2b
       emp2b1

   emp3
     emp3a
..
..
..

使用上述层次结构,我想为每个员工创建孩子。

预期输出:获取每个父母的孩子

Map<String,Set<String>>

{"empl1",["emp2","emp2a","emp2b","emp2b1","emp3","emp3a"]}

{"empl2",["emp2a","emp2b","emp2b1"]}

{"empl2b",["emp2b1"]}

{"emp3",["emp3a"]}

这可以使用现有的 Employee 类结构吗?

试过这个,但不起作用,不知道如何/在哪里停止循环 非常感谢任何帮助。谢谢!

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

【问题讨论】:

  • 是的,这是可能的。到目前为止,您尝试过什么?
  • 你这里有问题。您的目标数据结构仅允许 2 级深度。据我所知,emp2b1 是一个孙子,被压扁为直系子孙。那是你真正需要的吗?
  • 还有@jena84 你真的是指孩子吗?或者他们是由员工管理还是工作为员工或朋友的??
  • 它看起来像一棵树,为什么不是?

标签: java java-8


【解决方案1】:

试试这个。

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

输出

[emp1, emp2, emp2a, emp2b, emp2b1, emp3, emp3a]
{emp3=[emp3a], emp2=[emp2b1, emp2a, emp2b], emp1=[emp2b1, emp3, emp3a, emp2, emp2a, emp2b], emp2b=[emp2b1]}

【讨论】:

  • 非常感谢
【解决方案2】:

我认为解决方案的基础是这样的递归方法:

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

【讨论】:

    【解决方案3】:

    在您的 Employee 类中应该有这样的函数。

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

    我希望这能解决你的问题。

    【讨论】:

      【解决方案4】:

      我认为你的代码看起来不错,除了只需要删除“parentChildMap.put(parentEmpId, ls);”的最后一行,然后代码将按预期工作,当它通过所有节点时它会自动停止,因为你有条件那里的“isNotEmpty”。

      有关为什么需要删除该行的更多信息,因为List ls = parentChildMap.get(parentEmpId); 已经获得列表引用,您只需将元素添加到该列表中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-07
        • 2020-11-19
        • 1970-01-01
        • 1970-01-01
        • 2013-11-22
        • 2017-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多