代码之家  ›  专栏  ›  技术社区  ›  Extreme

如何避免stackoverflow异常

  •  2
  • Extreme  · 技术社区  · 6 年前

    我有一个层次对象列表,如果一个层次的值为零,我必须删除一个层次。

    我必须把所有的经理(雇员)都撤职 当且仅当emp工资为0且其下无员工时。 或者他手下的所有员工都没有薪水。 但如果经理的工资是零,而手下的员工没有零工资的话,情况就不一样了。

    如。

    emp(10)
        |---- empA(9)
                |---- empAa(8)
                |---- empAb(7)
                |---- empAc(0)
        |---- empB(7)
                |---- empBa(0)
                        |---- empBaa(0)
                                |---- empBaaa(0)
                |---- empBb(0)
                        |---- empBba(4)
    

    上面的结构必须修改如下。

    emp(10)
        |---- empA(9)
                |---- empAa(8)
                |---- empAb(7)
        |---- empB(7)
                |---- empBb(0)
                        |---- empBba(4)
    

    当输入列表很大时,出现stackoverflow异常。我应该如何增强这种逻辑来避免SOFE。

        removeHierarchy(List<Employee> managers){
            int count = 0;
            if(null != managers && !managers.isEmpty()){
                for(Employee manager: managers){
                List<Employee> toBeRemoved = new ArrayList<>();
                List<Employee> employees = manager.getEmployees();
                    if(0 == manager.getSalary()){
                        if(null == employees || employees.isEmpty()){
                            toBeRemoved.add(manager);
                        } else {
                            ++count;
                            removeHierarchy(employees);
                        }
                    } else {
                        removeHierarchy(employees);
                    }
                    managers.removeAll(toBeRemoved);
                }
            }
    
            for(int i=0; i < count; i++){
                removeHierarchy(managers);
            }
        }
    
    3 回复  |  直到 6 年前
        1
  •  4
  •   Dmitriy Dobrotvorskiy    6 年前

    我认为你的问题是你没有从名单上删除任何员工。如果列表有这样的配置,那么在最后一行中,您将进入无限循环。

    emp(0)
     |---- empA(0)
    

    最后一行应该是 managers.removeAll(toBeRemoved)

    以下是工作函数:

    void removeHierarchy( List<Employee> managers )
      {
        List<Employee> toBeRemoved = new ArrayList<>();
        for ( Employee manager : managers )
        {
          removeHierarchy( manager.getEmployees() );
          if (0 == manager.getSalary() && manager.getEmployees().isEmpty()) {
            toBeRemoved.add( manager );
          }
        }
        managers.removeAll( toBeRemoved );
      }
    

    full test code

        2
  •  0
  •   Maurice Perry    6 年前

    决定是保留还是删除 Employee ,您必须首先处理她的员工列表:

    void removeHierarchy(List<Employee> managers){
        if(null != managers && !managers.isEmpty()){
            List<Employee> toBeRemoved = new ArrayList<>();
            for(Employee manager: managers) {
                List<Employee> employees = manager.getEmployees();
                removeHierarchy(employees);
                if (0 == manager.getSalary()
                        && (null == employees || employees.isEmpty())) {
                    toBeRemoved.add(manager);
                }
            }
            managers.removeAll(toBeRemoved);
        }
    }
    
        3
  •  0
  •   AVVD    6 年前

    我认为这个程序有很多问题。

    1. 不能在列表上迭代并同时尝试操作它
    2. 没有逻辑可以删除已确定的经理/员工

    正如John所建议的,我正在添加能够执行所需任务的方法。除了我使用了Java 8语法糖之外,其他答案中提供的解决方案没有什么不同。

    public static boolean removeEmployee(Employee employee)
    {
        employee.setEmployees(employee.getEmployees().stream().filter(Employee::removeEmployee).collect(Collectors.toList()));
        return !(employee.getSalary()==0 && employee.getEmployees().size()==0);
    }
    

    注意:在创建employee对象时,请确保数组列表(雇员列表)不为空,即空数组列表。