package com.zy.common.utils; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.core.exception.CoolException; import com.zy.common.model.NavigateNode; @Component public class NavigateUtils { public synchronized List calcByStationId(Integer startStationId, Integer endStationId) { NavigateSolution navigateSolution = new NavigateSolution(); List> stationMap = navigateSolution.getStationMap(); NavigateNode startNode = navigateSolution.findStationNavigateNode(stationMap, startStationId); if (startNode == null){ throw new CoolException("未找到该 起点 对应的节点"); } NavigateNode endNode = navigateSolution.findStationNavigateNode(stationMap, endStationId); if (endNode == null){ throw new CoolException("未找到该 终点 对应的节点"); } NavigateNode res_node = navigateSolution.astarSearchJava(stationMap, startNode, endNode); if (res_node == null) { throw new CoolException("未找到该路径"); } ArrayList list = new ArrayList<>(); // 使用 visited 集合防止父链出现环导致死循环,同时设置安全步数上限 HashSet visited = new HashSet<>(); int maxSteps = stationMap.size() * stationMap.get(0).size() + 5; // 安全上限 int steps = 0; while (res_node != null && visited.add(res_node) && steps++ < maxSteps) { list.add(res_node); res_node = res_node.getFather();//迭代操作 } if (steps >= maxSteps) { throw new CoolException("路径回溯超出安全上限,疑似存在父链循环"); } Collections.reverse(list); //将每个节点里面的fatherNode至为null(方便后续计算时父节点过多导致显示的节点太多) for (NavigateNode navigateNode : list) { //父节点设置为null,不影响计算结果,不影响后续操作。 //此操作仅为后续排查处理提供视觉方便。 navigateNode.setFather(null); } //去重 HashSet set = new HashSet<>(); List fitlerList = new ArrayList<>(); for(NavigateNode navigateNode : list){ JSONObject valuObject = JSON.parseObject(navigateNode.getNodeValue()); if(set.add(valuObject.getInteger("stationId"))){ fitlerList.add(navigateNode); } } return fitlerList; } }