[英]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 : 这是一个代码审查评论,但是:
HashMap<Integer, LinkedList<Integer>> adj;
使用List而不是ArrayList和Map而不是Hashmap,所以HashMap<Integer, LinkedList<Integer>> adj;
becomes Map<Integer, List<Integer>>
成为Map<Integer, List<Integer>>
addeEgde
- c'mon! 方法名称addeEgde
- 来吧! 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.