2013-01-15 4 views
1

Я столкнулся с концептуальной проблемой со ссылками в java. Это моя реализация основного LinkedList:Концептуальные проблемы со ссылками на Java

Узлы:

class Node { 
    int data; 
    Node next = null; 

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

Список:

class LinkedList { 
    Node n = null; 
    Node start = null; 
    int flag = 0; 

    void insertion(int x) { 
    if(flag==0) 
    { 
     Node newnode = new Node(x); 
     n = newnode; 
     start = newnode; 
     flag = 1; 
     return; 
    } 

    Node newnode = new Node(x); 
    n.next = newnode; 
    n = n.next; 
    } 

    void deletion() { 
    Node str = start; 
    while(str.next.next != null) 
     str = str.next; 
    str.next = null;   
    } 

    void printlist() { 
    Node str = start; 
    while(str != null) { 
     System.out.println(str.data); 
     str = str.next; 
    } 
    } 
} 

тест:

public class Test31 { 
    public static void main(String[] args){ 
    LinkedList ll = new LinkedList(); 
    ll.insertion(5); 
    ll.insertion(15); 
    ll.insertion(25); 
    ll.insertion(35); 
    ll.insertion(45); 
    ll.insertion(55); 
    ll.deletion();ll.deletion(); 
    ll.printlist(); 
    } 
}      

выше программа отлично работает без каких-либо проблем, но если я заменю deletion() этот кусок кода:

void deletion() { 
    Node str = start; 
    while(str.next != null) 
    str = str.next; 
    str = null;  
} 

Тогда удаление элементов не происходит. Мне интересно узнать, почему это происходит. Использование str.next.next делает трюк, но если я использую метод удаления, приведенный выше, не должен ли он также добиться такого же эффекта только с еще одной итерацией цикла while?

+2

Отформатируйте свой код перед отправкой. Это очень трудно прочитать. Вы можете отредактировать свой вопрос. – jlordo

ответ

3

Это связано с тем, что один из объектов str.next по-прежнему ссылается на него (или потенциально start ссылается на него). Установив str в null, вы просто устанавливаете локальную переменную в этом методе на null, но, установив str.next на нуль, вы удаляете ссылку в этом объекте str.

Простой пример:

Node start = new Node(); 
Node another = new Node(); 
start.next = another; 
Node toDelete = another; 

Если вы сделаете это:

toDelete = null; 

В этом случае toDelete теперь null. start.next и another по-прежнему содержат ссылки на объект another. Даже если вы добавите это:

В этом случае все еще остается одна ссылка. start.next все еще указывает на исходный объект, изначально назначенный another.

Я думаю, что первый метод удаления на самом деле неправильно тоже, так как он никогда не будет удалять начальный узел и будет бросать NullPointerException, если у вас есть только один узел в ней с start.next является null и цикл в то время как пытается добраться до start.next.next , Я думаю, что это более точно:

void deletion() { 
    Node parent = null; 
    Node current = start; 
    while (current.next != null) { 
     parent = current; 
     current = current.next; 
    } 
    if (parent == null) { 
     start = null; 
     flag = 0; 
    } else { 
     parent.next = null; 
     n = parent; 
    }  
} 
+0

Я до сих пор не знаю @mbaumbach ......... насколько касается области str, то если я иду с этим кодом: void deletion() { Node str = start; в то время как (старт.next! = Null) старт = старт.следующий; start = null; start = str; \t \t } } здесь мы использовали начальную переменную экземпляра класса, тогда эффект удаления не производился ..... – JackSparrow

+0

Я удалил упоминание области видимости, поскольку я думаю, что это только добавление путаницы, поскольку это не действительно область вопрос, это проблема ссылочного владения. Я бы не предложил использовать переменную 'start', так как вы изменили бы начальную точку вашего списка. Когда вы вставляете новый узел, вы назначаете ссылку на переменную 'next' другого другого (или' start' для первой вставки). Чтобы действительно удалить его из списка, вам нужно удалить эту ссылку с узла-владельца. –

+0

это прекрасно ... Я понял, что ..... но я не могу понять, что если я установил str.next в null, тогда и начальная переменная класса будет указывать на объект, к которому указывает str.next в этом случае это не должно быть gc – JackSparrow

Смежные вопросы