我用于通过它的ID字段查找特定位置的深度优先搜索方法,在循环遍历位置对象列表时抛出Null指针异常。
我通过在findLocation()
和dfs()
上设置断点来调试错误,并且它仅触发dfs()
for循环中的NPE。因此,例如,如果我指定位置ID为“1”,则将正确返回位置,但如果我指定的位置ID大于1,则当代码进入dfs()
for循环时,我会获得NPE。
有人知道为什么for
循环在任何大于1的位置ID上给出NPE,尽管位置ID的范围是1到10。
这两种方法结合使用ID来查找位置:
public Location findLocation(Integer locationId) {
Location result = null;
for (Location l : location) {
System.out.println("In find method...");
result = dfs(new HashSet<Location>(), l, locationId); //line 180
if (result != null)
System.out.println("You are now in.." + result);
break;
}
return result;
}
private Location dfs(Set<Location> visitedAlready, Location current,
Integer id) {
if (current.id == id)
return current;
visitedAlready.add(current);
Location result = null;
for (Location l : current.location) { //line 194
result = dfs(visitedAlready, l, id);
if (result != null)
break;
}
return result;
}
输出的确切错误如下:
Exception in thread "main" java.lang.NullPointerException
at gmit.Location.dfs(Location.java:194)
at gmit.Location.findLocation(Location.java:180)
at gmit.GameParser.parse(GameParser.java:55)
at gmit.Main.main(Main.java:28)
答案 0 :(得分:2)
很高兴知道确切的错误消息是什么,等等。就此而言,在继续之前要求每个dfs()
打印当前可能会有所帮助。
有两个潜在的罪魁祸首:首先,传递的参数current
可能为空,这会产生current.id == id
和current.location
甚至可能visitedAlready.add(current)
的错误,具体取决于这个方法试图与参数完全一致。如果Location[]
处的current.location
(或任何集合)可能包含空条目,则可能会发生这种情况。
接下来是current.location
本身可能为null或者您无法通过for循环将Locations
拉出来,因此Location l : current.location
失败,因为{{ 1}}不对。实际上,current.location
对象具有包含其子节点的Location
属性听起来很奇怪。
通常,递归深度优先搜索如下所示:
location
如果您的代码与该示例不同,那么您将遇到麻烦。