Метод java.util.HashMap.get возвращает 2 значения для одного ключа. - PullRequest
0 голосов
/ 09 февраля 2019

Я создал класс Graph, который использует HashMap> для сохранения узлов в качестве ключей и соответствующих ребер в качестве значений.

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;
}

}

Затем я создал метод для обращения графика.Проблема в том, что метод java.util.HashMap.get возвращает 2 значения вместо одного, хотя мои ключи уникальны.Это приводит к добавлению ребра к более точному узлу, в который я хочу добавить ребро.

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;
}

Извините за все print.ln, но я хотел быть уверенным, где проблема возникает.Похоже, что revAdjList.get (y) .add (x), где y = 6 и x = 3, возвращает соответствующий ArrayList из ключа 6, как я хочу, но также из ключа 5. Ofc это приводит к добавлению ребра 3 к 6как я хочу, но он также добавляет его к 5.Мысли?

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 

1 Ответ

0 голосов
/ 09 февраля 2019

Проблема возникает в этой строке

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

Обратим внимание на проблему здесь и почему при ее печати "edge" дважды

revAdjList.get(h)

возвращает коллекцию Integerне одно целое число, поэтому оно может иметь столько целочисленных значений, сколько вы хотите, поскольку вы определяете его как коллекцию, а не как одну тонну.

Здесь вы добавляете несколько ребер

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

Если вы просто хотите 1 ребро, не делайте edges массивом.

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

следует определить как

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

После того, как выСделав это, вы можете удалить циклы и очистить код для работы с новым синтаксисом.

...