首页 > 解决方案 > 如何修复在另一个类中修改的私人列表

问题描述

对于一个学校项目,他们要求我们制作 dijkstra 算法。我有以下类:Node、Edge、graph 和 Dijkstra 使用 graph.getNodes(返回一个列表)并在使用 find path graph.getnodes 返回一个大小为 5 的列表而不是 getNodes 后将其存储在 findPath(在 djikstra 中)的局部变量中来自 graph.java findPath 来自 Djikstra.java

public List<Node> getNodes() {
    return nodes;
}

public void findPath (Node s, Node d) {
        System.out.println("nodeSize at begining of findpath : "+graph.getNodes().size());
        List<Node> nodes = graph.getNodes();
        dijkstraTable = new Map[nodes.size()];
        //verify paramaters
        if(!nodes.contains(s)) throw new InvalidParameterException("the source node is not valid");
        if(!nodes.contains(d)) throw new InvalidParameterException("the destination node is not valid");
        if(s == null || d == null ) throw new NullPointerException("s or d are null");
        Edge edge0 = new Edge(s,s,0);
        Map<Node,Edge> map = new HashMap<Node,Edge>();
        map.put(s, edge0);
        int i =0;
        dijkstraTable[i] = map;
        //iteration > 0 
        while(!nodes.isEmpty()) {
            i++;
            if (i==nodes.size()) break;
            Map<Node,Edge> newMap = new HashMap<Node,Edge>();
            map = dijkstraTable[i-1]; //last iteration map 
            //get minimum last iteration
            Node min = getMinimum(map);
            //mark it as "visited" 
            nodes.remove(min);
            //add it to the path
            List<Edge> edges = graph.getEdgesGoingFrom(min);
            System.out.println("nodeSize in loop: "+graph.getNodes().size());
            for(Edge edge : edges) {
                Node key = edge.getDestination();
                if(!map.containsKey(key)) { //create it if doesnt exist
                    newMap.put(key, edge);
                }else { //make sure to have the minimum value
                    if(getMinimum(map.get(key), edge) == edge) newMap.put(key, edge);
                    else newMap.put(key, map.get(key));
                }
            }//endfor
            path.add(map.get(min));
            dijkstraTable[i] = newMap;
        }
        System.out.println("nodeSize at end of findpath : "+graph.getNodes().size());
    }

输出是

findpath 开头的 nodeSize :7

循环中的节点大小:6

循环中的节点大小:5

循环中的节点大小:5

循环中的节点大小:5

findpath 末尾的 nodeSize :5

每次都应该是7

标签: java

解决方案


你的问题在这里:

public List<Node> getNodes() {
    return nodes;
}
...

List<Node> nodes = graph.getNodes();

您正在修改方法中的“私人”列表findPath。如果要避免修改,请使用Collections.unmodifiableList(nodes)intgetNodes()或在其中创建一个新列表findPath并传递graph.getNodes()给列表构造函数。


推荐阅读