避免死循环的算法
示例:
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、效果:


浙公网安备 33010602011771号