-2

NullPointerException当我尝试运行此代码时,我得到了一个。我已将Nodes2、3 和 4 作为子节点分配给Node1. 我试图创建一个方法,该方法将遍历 Node1 中的所有子节点并返回列表。我不确定我做错了什么。

public class TestingArrays2 {

    List<Node> myList1;
    List<Node> myList2;
    List<Node> myList3;
    List<Node> myList4;

    private Node Node1;
    private Node Node2;
    private Node Node3;
    private Node Node4;

    public TestingArrays2() {
        myList1 = new ArrayList<Node>();
        myList2 = new ArrayList<Node>();
        myList3 = new ArrayList<Node>();
        myList4 = new ArrayList<Node>();

        myList1.add(Node2);
        myList1.add(Node3);
        myList1.add(Node4);

        Node1 = new Node("One", myList1);
        Node2 = new Node("Two", myList2);
        Node3 = new Node("Three", myList3);
        Node4 = new Node("Four", myList4);

        List<Node> allNodesArray = nodeArray(Node1);

        for (int i = 0; i < allNodesArray.size(); i++){
            System.out.println(allNodesArray.get(i).label);
        }
    }

    public static void main(String arg[]) {
        TestingArrays2 testArray = new TestingArrays2();
    }

    public List<Node> nodeArray(Node n){
        List<Node> tempList = new ArrayList<Node>();

        for (int i = 0; i < n.children.size(); i++){
            tempList.add(n.children.get(i));
        }

    return tempList;
    }
}
4

3 回答 3

2

你不是在创建你的Nodes. 看到这些线...

private Node Node1;
private Node Node2;
private Node Node3;
private Node Node4;

这些只是将变量声明为能够包含类型的对象Node。然而,它们最初是从一个null值开始的——即它们是空的。

然后你打电话给这些线路......

myList1.add(Node2);
myList1.add(Node3);
myList1.add(Node4);

这会将null值插入到您的List中,因为您正在尝试添加尚未创建的对象。

因此,您需要更改代码,以便这些行...

Node1 = new Node("One", myList1);
Node2 = new Node("Two", myList2);
Node3 = new Node("Three", myList3);
Node4 = new Node("Four", myList4);

出现在您尝试将myList1.add()它们添加到列表之前。这将首先创建Node对象,然后可以将其添加到您的List.

正如评论中提到的@BalusC,它for稍后在您的代码中的循环中失败,因为它试图调用.label一个null对象。按照上面的建议更正顺序将更正此问题,因为您的所有对象List现在都是Nodes.

于 2012-05-27T05:40:29.433 回答
1

这个:

myList1.add(Node2);
myList1.add(Node3);
myList1.add(Node4);

Node1 = new Node("One", myList1);
Node2 = new Node("Two", myList2);
Node3 = new Node("Three", myList3);
Node4 = new Node("Four", myList4);

您正在尝试在创建节点之前将它们添加到列表中。

于 2012-05-27T05:41:48.063 回答
0

您的问题已经给出了很好的答案。

查看您的代码,我有几个建议的修改。

您正在测试类(的构造函数)中完成所有工作。在可能的情况下将其委托给 Node 类是更好的设计。也尽量不要在构造函数中做“工作”,只是初始化。

还可以查看我应用的代码约定,例如使用名词作为类名和以小写字母开头的变量名。

public class ArrayTest2 {

    public static void main(String arg[]) {

        Node node1 = new Node("One");

        node1.add(new Node("Two"));
        node1.add(new Node("Three"));
        node1.add(new Node("Four"));

        // this calls the toString method of node1
        System.out.println(node1);
    }

}

public class Node {

    private final String name;
    private final List<Node> children;

    public Node(String name) {
        this.name = name;
        this.children = new ArrayList<Node>();
    }

    public String getName() {
        return name;
    }

    public void add(Node children) {
        children.add(child);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(name);
        if(children.size() > 0) {
            sb.append("(");
            String separator = "";
            for (Node child : children){
                sb.append(separator).append(String.valueOf(child));
                separator = ",";
            }
            sb.append(")");
        }
        return sb.toString();
    }
}

请注意,children 字段是私有的,并且没有 getter。提供对“children”等内部数据结构的直接访问被认为是不好的做法,因此我提供了一种“add”方法来添加节点。通过这种方式,类可以控制其数据发生的情况,这是一个重要的 OO 设计原则。

toString 方法构建节点的字符串表示。它附加节点名称,然后,如果有子节点,则将每个子节点的字符串表示附加到用括号括起来的逗号分隔列表中,因此应该打印如下内容:

One(Two,Three,Four)

例如更复杂的结构:

Node node1 = new Node("One");
Node node2 = new Node("Two");
Node node3 = new Node("Three");
Node node4 = new Node("Four");
Node node5 = new Node("Five");
Node node6 = new Node("Six");
node1.add(node2);
node1.add(node3);
node2.add(node4);
node4.add(node5);
node4.add(node6);

应该给:

One(Two(Four(Five,Six)),Three)

免责声明:我的代码是手工制作、未经编译和未经测试的

于 2012-05-27T09:36:09.643 回答