如何使用递归深入搜索对象集合?

时间:2015-04-09 16:05:22

标签: arrays object recursion depth-first-search java-5

我用于通过它的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)

1 个答案:

答案 0 :(得分:2)

很高兴知道确切的错误消息是什么,等等。就此而言,在继续之前要求每个dfs()打印当前可能会有所帮助。

有两个潜在的罪魁祸首:首先,传递的参数current可能为空,这会产生current.id == idcurrent.location甚至可能visitedAlready.add(current)的错误,具体取决于这个方法试图与参数完全一致。如果Location[]处的current.location(或任何集合)可能包含空条目,则可能会发生这种情况。

接下来是current.location本身可能为null或者您无法通过for循环将Locations拉出来,因此Location l : current.location失败,因为{{ 1}}不对。实际上,current.location对象具有包含其子节点的Location属性听起来很奇怪。

通常,递归深度优先搜索如下所示:

location

如果您的代码与该示例不同,那么您将遇到麻烦。