如何修复在另一个类中修改的私有列表

问题描述 投票:1回答:2

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

nodeSize in loop:6

nodeSize in loop:5

nodeSize in loop:5

nodeSize in loop:5

findpath末尾的nodeSize:5

每次都应该是7

java
2个回答
1
投票

你的问题在这里:

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

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

您正在使用findPath方法修改“私人”列表。如果你想避免修改,可以使用Collections.unmodifiableList(nodes) int getNodes()or在findPath中创建一个新列表并将graph.getNodes()传递给列表构造函数。


1
投票

更改

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

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

这将在findPath方法中创建列表的本地副本。

或者你可以改变

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

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

这将在getNodes()方法中返回列表的副本。

© www.soinside.com 2019 - 2024. All rights reserved.