避免死循环的算法
示例:
1、Employee类
public class Employee { private String userId; private List<Employee> employeeList; public Employee(String userId) { super(); this.userId = userId; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public List<Employee> getEmployeeList() { return employeeList; } public void setEmployeeList(List<Employee> employeeList) { this.employeeList = employeeList; } }
2、死循环代码:
public class DeadCycleTest { public static void main(String[] args) { Employee employee1 = new Employee("张三"); Employee employee2 = new Employee("李四"); Employee employee3 = new Employee("王五"); Employee employee4 = new Employee("小六"); List<Employee> employeeList1 = new ArrayList<>(); //张三的下级是李四 employeeList1.add(employee2); employee1.setEmployeeList(employeeList1); List<Employee> employeeList2 = new ArrayList<>(); //李四的下级是王五 employeeList2.add(employee3); employee2.setEmployeeList(employeeList2); List<Employee> employeeList3 = new ArrayList<>(); employeeList3.add(employee1); //A、造成死循环,这里王五的下级又变成了张三 employeeList3.add(employee4); employee3.setEmployeeList(employeeList3); //需求,找出张三的所有下级,忽略掉死循环,就是到A这里,不再往下面循环 for(Employee childrenEmployee : employeeList1) { test(employee1,childrenEmployee); } } private static void test(Employee parentEmployee,Employee childrenEmployee) { System.out.println(parentEmployee.getUserId()+"的下级是"+childrenEmployee.getUserId()); List<Employee> chilrenEmployeeIndexList = childrenEmployee.getEmployeeList(); if(chilrenEmployeeIndexList != null) { for(Employee chilrenEmployeeIndex : chilrenEmployeeIndexList) { test(childrenEmployee,chilrenEmployeeIndex); } } } }
3、死循环效果:
4、跳过死循环代码 (A-1,A-2,B-1,B-2)是跳出死循环的关键步骤
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Title: * @Description:TODO * @Company:HF * @ClassName:DeadCycleTest.java * @Author:wushigao * @CreateDate:2022年11月22日下午4:02:36 * @UpdateUser:wushigao * @UpdateDate:2022年11月22日 下午4:02:36 * @Version:1.0 */ public class DeadCycleTest { private static Map<Employee,List<Employee>> childrenAndParentListMap; public static void main(String[] args) { childrenAndParentListMap = new HashMap<>(); Employee employee1 = new Employee("张三"); Employee employee2 = new Employee("李四"); Employee employee3 = new Employee("王五"); Employee employee4 = new Employee("小六"); List<Employee> employeeList1 = new ArrayList<>(); //张三的下级是李四 employeeList1.add(employee2); employee1.setEmployeeList(employeeList1); List<Employee> employeeList2 = new ArrayList<>(); //李四的下级是王五 employeeList2.add(employee3); employee2.setEmployeeList(employeeList2); List<Employee> employeeList3 = new ArrayList<>(); employeeList3.add(employee1); //A、造成死循环,这里王五的下级又变成了张三 employeeList3.add(employee4); employee3.setEmployeeList(employeeList3); //需求,找出张三的所有下级,忽略掉死循环,就是到A这里,不再往下面循环 for(Employee childrenEmployee : employeeList1) { test(employee1,childrenEmployee); } } private static void test(Employee parentEmployee,Employee childrenEmployee) { //A-1、判断是否死循环,看父亲是否已经作为别人的儿子,也就是父亲的父亲有哪些 if(childrenAndParentListMap.keySet().contains(parentEmployee)) { List<Employee> parentEmployeeList = childrenAndParentListMap.get(parentEmployee); //A-2,如果父亲的父亲有自己,则存在死循环了 if(parentEmployeeList.contains(childrenEmployee)) { System.out.println(parentEmployee.getUserId()+"和"+childrenEmployee.getUserId()+"死循环!"); return; } } //B-1 不存在死循环,则存储我的所有父亲 if(childrenAndParentListMap.containsKey(childrenEmployee)) { List<Employee> parentEmployeeList = childrenAndParentListMap.get(childrenEmployee); parentEmployeeList.add(childrenEmployee); //B-2 除了直接父亲,把父亲以上的所有所有级别都存储为自己的父亲 getParentAllFolder(parentEmployeeList,parentEmployee); }else { List<Employee> parentEmployeeList = new ArrayList<>(); parentEmployeeList.add(parentEmployee); childrenAndParentListMap.put(childrenEmployee, parentEmployeeList); getParentAllFolder(parentEmployeeList,parentEmployee); } System.out.println(parentEmployee.getUserId()+"的下级是"+childrenEmployee.getUserId()); List<Employee> chilrenEmployeeIndexList = childrenEmployee.getEmployeeList(); if(chilrenEmployeeIndexList != null) { for(Employee chilrenEmployeeIndex : chilrenEmployeeIndexList) { test(childrenEmployee,chilrenEmployeeIndex); } } } private static void getParentAllFolder(List<Employee> parentList,Employee parentEmployee) { if(childrenAndParentListMap.keySet().contains(parentEmployee)) { List<Employee> parentListIndex = childrenAndParentListMap.get(parentEmployee); if(parentListIndex.size() > 0) { parentList.addAll(parentListIndex); for(Employee employeeIndex : parentListIndex) { getParentAllFolder(parentList,(Employee)employeeIndex); } } } } }
5、效果: