简体   繁体   English

Java - Graph.java中的NullPointerException

[英]Java - NullPointerException in Graph.java

I am trying to create an undirected graph that is read from a text file. 我正在尝试创建一个从文本文件中读取的无向图。 However I keep getting a NullPointerException. 但是我不断收到NullPointerException。 This is my Graph class: 这是我的Graph类:

Graph.java: Graph.java:

    package testalgo;

    import java.io.File;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Scanner;


    public class Graph

    {   


            ArrayList<Integer> vertices = new ArrayList<Integer>();
           HashMap<Integer, LinkedList<Integer>> adj;
           static Scanner sc;
            public Graph(ArrayList<Integer> verts ){

                   adj =new HashMap<Integer, LinkedList<Integer>>();
            }

            public static void main(String[] args) {

                try{
                sc = new Scanner(new File("graph1.txt"));
                }
                catch(Exception e){

                    System.out.println(e);
                }

                while(sc.hasNext()){

                    int a = Integer.parseInt(sc.next());
                    int b = Integer.parseInt(sc.next());
                    Graph g = new Graph(new ArrayList<Integer>());
                    g.addVertex(a);
                    g.addeEgde(a, b); // this is line 46
                    g.addeEgde(b, a);


                }

                 sc.close();
            }

            public void addVertex(int v){


                for (int i = 1; i < vertices.size(); ++i) {
                adj.put(i, new LinkedList<Integer>());}

            }

            public  void addeEgde(int v1, int v2) {

                adj.get(v1).add(v2); // this is line 68
            }

            public List<Integer> getNeighbors(int v) {
                return adj.get(v);
         }
  }

And this is the error message that I am getting: 这是我得到的错误消息:

Exception in thread "main" java.lang.NullPointerException
    at testalgo.Graph.addeEgde(Graph.java:68)
    at testalgo.Graph.main(Graph.java:46)

Thank you for all your help! 谢谢你的帮助!

I don't see anywhere in your code where you're populating the the adj map with v as a key. 我没有在你的代码中看到用v作为键填充adj映射的任何地方。 Hence adj.get(v1) will return null . 因此adj.get(v1)将返回null You've only declared adj ; 你只宣布了adj ; you need to populate it as well. 你也需要填充它。

All I see is: 我只看到:

for (int i = 1; i < vertices.size(); ++i) {
    adj.put(i, new LinkedList<Integer>());
}

Since vertices is empty to begin with, you won't be inserting anything into your map. 由于vertices是空的,因此您不会在地图中插入任何内容。

Did you mean: 你的意思是:

adj.put(v, new LinkedList<Integer>());

instead? 代替?

In response to your comment: you need to add another entry for b in your adjacency list: 在回复您的评论时:您需要在邻接列表中为b添加另一个条目:

g.addVertex(a);
g.addVertex(b); // <--- you need this as well
g.addeEgde(a, b);
g.addeEgde(b, a); // <--- otherwise you'll get a NPE here

You probably have invoked addeEdge without having added any vertex , as 您可能在没有添加任何vertex情况下调用了addeEdge

for (int i = 1; i < vertices.size(); ++i)
{
  adj.put(i, new LinkedList<Integer>());
}

Will not put any LinkedList instance in adj ( vertices.size() is 0). 不会将任何LinkedList实例放在adj中( vertices.size()为0)。

Therefore, 因此,

adj.get(v1).add(v2);

Will throw a NullPointerException , as adj.get(v1) will return null and you are invoking add on null . 将抛出NullPointerException ,因为adj.get(v1)将返回null并且您正在调用add on null

Try declaring: 尝试声明:

private static int count = 0;

In class body, and then, in addVertex : 在类体中,然后在addVertex

adj.put(count++, new LinkedList<Integer>());

This one will put a new LinkedList in your Map every time addVertex is invoked. 每次调用addVertex这个都会在Map放置一个新的LinkedList

Alternatively, for the map index: 或者,对于地图索引:

public void addVertex(int vertexIndex)
{
  adj.put(vertexIndex, new LinkedList<Integer>());
}

In addition, ensure that adj.get(v1) will not be null by making a null check comparison before calling add on it: 另外,在调用add之前进行空检查比较,确保adj.get(v1)不为null:

LinkedList<Integer> vertex = adj.get(v1);
if(vertex != null)
{
  vertex.add(v2);
}

Also, cosider that g.addeEgde(b, a); 另外,g.addeEgde(b,a)的cosider; applies to a vertex that does not exist and will be a source of NullPointerException too. 适用于不存在的顶点,也是NullPointerException的源。

UPDATE: In the case you are attempting to insert values in a sequence (sequential index), using a Map for your vertexes is not the mostly efficient way of doing this (takes O(logn) complexity time of indexing). 更新:如果您尝试在序列中插入值(顺序索引),则使用顶点Map不是最有效的方法(索引的O(logn)复杂时间)。 I suggest that you use an ArrayList instead: 我建议您使用ArrayList

ArrayList<LinkedList<Integer>> adj;

And in your addVertex: 在你的addVertex中:

adj.add(new LinkedList<Integer>());

And when indexing: 索引时:

adj.get(yourIndex);

This one will be much more efficient (takes O(1) complexity time in indexing). 这个将更有效(在索引中花费O(1)复杂时间)。

UPDATE 2: If your case is an adjacency list, which probably is, the Map is better to use than the ArrayList , as you do not have a sequential indexing. 更新2:如果你的情况是一个邻接列表,可能是,使用Map比使用ArrayList更好,因为你没有顺序索引。 Take in mind you must add vertices by adjacency value and NOT sequential indexing, as Vivin Paliath mentioned. 请注意,必须按邻接值和非顺序索引添加顶点,如Vivin Paliath所述。

This is more of a code review comment, but : 这是一个代码审查评论,但是:

  1. Formatting - your IDE can do this (assuming you are using one..). 格式化 - 您的IDE可以执行此操作(假设您使用的是..)。
  2. Use List rather than ArrayList, and Map rather than Hashmap, so HashMap<Integer, LinkedList<Integer>> adj; 使用List而不是ArrayList和Map而不是Hashmap,所以HashMap<Integer, LinkedList<Integer>> adj; becomes Map<Integer, List<Integer>> 成为Map<Integer, List<Integer>>
  3. The method name addeEgde - c'mon! 方法名称addeEgde - 来吧!
  4. You don't actually use the ArrayList<Integer> that you pass to the constructor of Graph - do you really need it? 您实际上并没有使用传递给Graph构造函数的ArrayList<Integer> - 您真的需要它吗?

From experience of implementing (far too many) graph objects, you might want to consider how you would make one that could use a fixed int matrix instead of the adjacency list approach. 根据实现(太多)图形对象的经验,您可能想要考虑如何使用固定的int矩阵而不是邻接列表方法。 Both implementations can be useful, but in different circumstances. 两种实现都很有用,但在不同的情况下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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