简体   繁体   中英

java.util.HashMap.get method returns 2 values for one key

I made a Graph class which uses a HashMap> to keep nodes as keys and corresponding edges as values.

public class GraphAL {
private HashMap<Integer, ArrayList<Integer>> adjList;
private ArrayList<Integer> vertices;
int numberOfNodes;
boolean visited[];

GraphAL(HashMap<Integer, ArrayList<Integer>> adjList, 
        ArrayList<Integer> vertices, int numberOfNodes){
    this.adjList = adjList;
    this.vertices = vertices;
    this.numberOfNodes = numberOfNodes;
    visited = new boolean[this.numberOfNodes];
}

public HashMap<Integer, ArrayList<Integer>>  getAdjList() {
    return adjList;
}

public ArrayList<Integer>  getVertices() {
    return vertices;
}

public int getNumeberOfNodes()
{
    return numberOfNodes;
}

public boolean[] getVIsitedNodes()
{
    return visited;
}

public void setVisitedNodesToTrue(int node)
{
    visited[node] = true;
}

}

I made then a method to reverse the graph. The problem is that java.util.HashMap.get method returns 2 values instead of one although my keys are unique. This leads to adding an edge to more than the exact node where I want to add an edge.

public static GraphAL reverseGraph(GraphAL g)
{
    HashMap<Integer, ArrayList<Integer>> revAdjList = new HashMap<Integer, ArrayList<Integer>>();

    ArrayList<Integer> revVertices = new ArrayList<Integer>();

    System.out.println("Printing in for loop");
    for(Integer x:g.getVertices())
    {
        System.out.println("x = " + x);
        ArrayList<Integer> edges = new ArrayList<Integer>();
        edges.add(x);
        System.out.println("Edges: ");
        for(Integer m:edges)
        {
        System.out.print(m +  " ");
        }
        for(Integer y:g.getAdjList().get(x))
        {
            System.out.println("y = " + y);

            if(!revVertices.contains(y)) 
            {
                    revVertices.add(y);
                    System.out.println("RevVertices: ");
                    for(Integer n:revVertices)
                    {
                    System.out.print(n + " ");
                    }
            }
            if(revAdjList.containsKey(y))
            {
                for(Integer o:revAdjList.get(5))
                {
                    System.out.println(5 + " contains " + o);
                }
                System.out.println("adding " + x + " to " + y);

                revAdjList.get(y).add(x);

                for(Integer o:revAdjList.get(y))
                {
                    System.out.println(y + " contains " + o);
                }

                for(Integer o:revAdjList.get(5))
                {
                    System.out.println(5 + " contains " + o);
                }

            }
            else
            {
            revAdjList.put(y, edges);
            System.out.println("putting " + x + " at " + y);
            }
            System.out.println("Current AdjList: ");
            for(Integer h:revVertices)
            {
                System.out.print("vertice is: " + h + " ");
                for(Integer j:revAdjList.get(h))
                {
                    System.out.print("edge : " + j + " ");

                }
                System.out.println();
            }
        }

    }
    System.out.println("Done printing in for loop");

    GraphAL revGraph = new GraphAL(revAdjList, revVertices, g.getNumeberOfNodes());
    return revGraph;
}

Sorry for all the print.ln's but I wanted to be sure where the problem is occurring. It looks like revAdjList.get(y).add(x), where y=6 and x=3, is returning the corresponding ArrayList from key 6 like I want but also from key 5. Ofc this leads to adding edge 3 to 6 like I want but it's also adding it to 5 as well. Thoughts?

x = 3
Edges: 
3 y = 6
5 contains 8
adding 3 to 6
6 contains 8
6 contains 3
5 contains 8
5 contains 3
adding 3 to 6
Current AdjList: 
vertice is: 1 edge : 7 
vertice is: 2 edge : 5 
vertice is: 3 edge : 9 
vertice is: 7 edge : 9 
vertice is: 4 edge : 1 
vertice is: 5 edge : 8 edge : 3 
vertice is: 6 edge : 8 edge : 3 

The problem happens on this line

for (Integer j : revAdjList.get(h)) {
    System.out.print("edge : " + j + " ");
}

Lets point out the issue here and why its printing out the "edge" twice

revAdjList.get(h)

returns a collection of Integer not a single Integer so it can have as many integer values as you want since you are defining it as a collection and not a single-ton.

You are adding multiple edges from here

for (Integer m : edges) {
    System.out.print(m + " ");
}

If you just want 1 edge, don't make edges an array.

HashMap<Integer, ArrayList<Integer>> revAdjList = new HashMap<>();

should be defined as

HashMap<Integer, Integer> revAdjList = new HashMap<>();

After you have done that, you can remove the loops and clean up the code to work with the new syntax.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM