对象值为null

时间:2012-08-30 22:20:19

标签: java null nullpointerexception linked-list

我是Java的新手,我正在尝试实现一个链接列表(我知道为此目的存在一个列表类,但是从头开始让我理解语言在内部是如何工作的)

在main方法中,我声明4个节点并初始化3.链表的头节点设置为null。 第一次使用参数head和newNode调用add函数时,head为null,因此我初始化head并为其赋值newNode。 在main方法中,我希望head对象应该具有从add方法设置的新值。但是头仍然是空的。

我很高兴理解为什么会这样。

如果代码不干净,请道歉,非常感谢!

public class LinkedList
{
    public void add(Node newNode, Node head)
    {
        if(head == null) 
        {
            head = new Node(); 
            head = newNode;              
        }
        else 
        {
            Node temp = new Node(); 
            temp = head; 

            while(temp.next!=null)
            {
                temp = temp.next; 
            }
            temp.next = newNode; 
        }    
    }

    public void traverse(Node head)
    {
        Node temp = new Node(); 
        temp = head; 

        System.out.println("Linked List:: ");

        while(temp.next!=null);  
        {
           System.out.println(" "  + temp.data); 
            temp = temp.next;
        }
    }

    public static void main(String args[])
    {
        Node head = null;
        Node newNode = new Node(null, 5); 
        Node newNode2 = new Node(null, 15); 
        Node newNode3 = new Node(null,30); 

        LinkedList firstList = new LinkedList(); 

        firstList.add(newNode,head); 

       // Part that I don't understand
       // why is head still null here? 

        if(head==null)
        {
         System.out.println("true");
        }

        firstList.traverse(head); 
        firstList.add(newNode2,head); 
        firstList.traverse(head); 
        firstList.add(newNode3,head); 
        firstList.traverse(head); 

    }

}

public class Node
{
    public Node next; 
    public int data; 

    public Node(Node next, int data)
    {
        this.next = next; 
        this.data = data; 
    }

    public Node()
    {
        this.next = null; 
        this.data = 0; 
    }

}

5 个答案:

答案 0 :(得分:2)

Java方法参数是按值传递的。

public void add(Node newNode, Node head)
{
    if(head == null) 
    {
        head = new Node(); 
        head = newNode;              
    }
    ...

以上仅修改了head范围内的局部变量add。无法在head范围内引用局部变量main。如果您希望调用者能够检索新值,则可能应返回该值。


说实话,面向对象编程的一个主要原则是封装;您head的{​​{1}}理想情况下应该是内部维护的字段。为什么它应该是一个单独的部分?如果您真的希望LinkedList被隔离,那么为什么headtraverse不是静态的?你应该尝试修改你的设计。我决定重写你的代码here

add

...然后,测试:

final class List {

  private Node head;

  public void add(final Node node) {
    if (head == null) {
      head = new Node();
    }
    Node cur;
    for (cur = head; cur.next != null; cur = cur.next)
      ;
    cur.next = node;
  }

  public String toString() {
    final StringBuilder builder = new StringBuilder("Linked List::");
    for (Node cur = head.next; cur != null; cur = cur.next) {
      builder.append("\n ").append(cur.data);
    }
    return builder.toString();
  }
}

final class Node {

  int data;
  Node next;

  Node(final int data) {
    this.data = data;
  }

  Node() { }
}

答案 1 :(得分:2)

我认为问题出在“添加”功能中。您只是在函数范围内更改“head”的值,而不是在其外部。您可以找到有关Java处理传递参数值here的方式的有用信息。

Java中LinkedList的一个很好的实现是here

答案 2 :(得分:1)

使“head”引用另一个节点对调用代码没有影响(java传递引用,在java中是地址的“值”)。

你需要永久引用头部,所以把它作为你班级的一个领域:

private Node head = new Node(); // the head of your Node tree

public void add(Node newNode, Node parent) {
    // add node to parent.
    // for some calls, the parent will be the head
}

答案 3 :(得分:0)

    firstList.add(newNode,head); 

   /*
    Part you should know is, head is a local variable pointing to null.
    Passing head as parameter doesn't make it feasible to alter this local variable.
    Your check is worthless.
    Make public Node add(Node newNode, Node head) and return head from there.
   */ 
    head=firstList.add(newNode,head);

    if(head==null)
    {
     System.out.println("true");
    }

答案 4 :(得分:0)

这样可以更好地植入您的链接列表。请注意:

  1. _head应该是私人会员
  2. Node是一种内在机制。您应该为add方法而不是Node对象提供数据参数
  3. 我写了这个,很简单,但基于你的代码,实现

    public class LinkedList{
    private Node _head;
    public void add(int data)
    {               
            //Understand this code! What happens if _head=null?                 
            _head=new Node(_head,data); 
            /*
                 //Use the following code for a "Normal" nodes-order
                 if(_head==null)
                    _head=new Node(null,data);
                 else{
                   Node temp=_head;
                   while( temp.next!=null)
                      temp=temp.next;            
                   temp.next=new Node(null,data); 
                 }
            */
    }
    public void traverse()
    {
        System.out.println("Linked List:: ");
        Node temp=_head;
        while(temp!=null){
                System.out.println(" "  + temp.data); 
                temp = temp.next;
        }
    }
    public LinkedList(){
        _head=null;         //null is our lists anchor
    }
    
    public static void main(String args[])
    {
        LinkedList firstList = new LinkedList(); 
    
        firstList.add(5); 
        firstList.traverse(); 
        firstList.add(15); 
        firstList.traverse(); 
        firstList.add(30); 
        firstList.traverse(); 
    
    }
    

    }