如何避免stackoverflow异常

时间:2018-07-27 01:52:51

标签: java recursion arraylist java-8 stack-overflow

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

我必须删除所有经理(雇员) 当且仅当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 个答案:

答案 0 :(得分:4)

我认为您的问题是您实际上没有从列表中删除任何员工。如果列表具有这样的配置-您将在最后一行无限循环。

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

答案 1 :(得分:0)

我认为该程序存在多个问题。

  1. 您无法遍历列表并尝试同时操作它
  2. 没有逻辑来删除已确定的经理/雇员

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

localhost

注意:请确保您的数组列表(员工列表)不为null,即创建员工对象时为空数组列表。

答案 2 :(得分:0)

要决定是保留还是删除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);
    }
}