2017-09-05 4 views
0

J'ai une classe:Java passe par référence avec le numéro de ListNode

class ListNode { 
    int val; 
    ListNode next; 
    ListNode(int x) { val = x; } 
} 

Et la fonction d'imprimer LinkedList est:

public static void printLinkedNode(ListNode l){ 
     while(l != null){ 
      System.out.print(l.val+" "); 
      l = l.next; 
     } 
     System.out.println(" "); 
    } 

Dans ma fonction principale, je crée un ListNode appelé test:

ListNode test = new ListNode(1); 
head.next = new ListNode(2); 
head.next.next = new ListNode(3); 
head.next.next.next = new ListNode(4); 

Si je fais:

ListNode fast = head, slow = head; 
fast = fast.next.next; 
printLinkedNode(head); // I get 1->2->3->4 

Si je fais B:

ListNode fast = head, slow = head; 
fast.next = fast.next.next; 
printLinkedNode(head); // I get 1->3->4 

Je suis confus pourquoi A, la tête est le 1-> 2-> 3-> 4, mais pas 3-> 4? J'ai lu quelques messages au sujet Is Java “pass-by-reference” or “pass-by-value”?, mais ne peut toujours pas comprendre ..

Si je fais C:

  ListNode fast = head, slow = head; 
      fast = fast.next.next; 
      printLinkedNode(fast); //3->4 
      printLinkedNode(head); //1->2->3->4 
      fast.next = new ListNode(5); 
      printLinkedNode(fast); //3->5 
      printLinkedNode(head); //1->2->3->5, why the head will change? 

Je suis confus pourquoi la tête change lorsque nous fast.next = nouveau ListNode (5); Je pense que rapide n'est pas assigner avec la tête?

+0

'head' références toujours le même objet. Dans A vous laissez 'fast' référencer la même instance que' head', puis changez cette référence pour le noeud suivant tout en gardant la référence 'head' inchangée. Java est une valeur de transmission en ce sens que la "valeur" d'une référence est copiée et transmise (pas l'adresse de ou le pointeur vers une référence). Pensez aux références Java comme une sorte de pointeur: 'fast = head' signifie que vous avez deux" pointeurs "pointant vers la même adresse (ils ont la même valeur) et quand vous faites' fast = xxx' vous laissez pointer 'fast' sur une autre adresse (vous changez la valeur de ce pointeur seulement). – Thomas

Répondre

3

Lorsque vous affecter une variable, vous le faites pointer (référence) vers un objet spécifique. Lorsque vous le réattribuer, vous en faites point (référence) à un autre objet, vous ne remplacez pas la valeur de référence, il tient:

ListNode fast = head, slow = head; // fast has a reference to head. 
fast = fast.next.next;    // fast has a reference to fast.next.next. You are not overwriting head, just fast. 
printLinkedNode(head); // I get 1->2->3->4 

Au lieu de cela, si vous modifiez quelque chose l'intérieur un objet référencé, vous ll modifier l'objet original:

ListNode fast = head, slow = head; // fast has a reference to head 
fast.next = fast.next.next;  // by editing fast.next, you edit head.next 
printLinkedNode(head); // I get 1->3->4 

Mise à jour pour usecase C:

ListNode fast = head, slow = head; // fast = head = (1) 
fast = fast.next.next;    // fast = fast.next.next = (3). head is still (1) 
printLinkedNode(fast);    // 3->4 -> because fast points to head.next.next (3) 
printLinkedNode(head);    // 1->2->3->4 -> head wasn't modified by any of the previous instructions 

// here fast points to head.next.next. So fast.next is the same as head.next.next.next (4). 
fast.next = new ListNode(5);  // Overwrites fast.next, it was (4), becomes (5) 
printLinkedNode(fast);    // 3->5 
printLinkedNode(head);    // 1->2->3->5 

Pour le rendre plus facile à comprendre:

Disons que nous avons des objets a, b et c de type ListNode:

ListNode a = new ListNode(1); 
ListNode b = new ListNode(2); 
ListNode c = new ListNode(3); 

ListNode d = a; // variable d now points to object a 
d.next = b;  // since d points to a, this statement modifies a.next 
d = c   // This does *not* modify a. It just makes d point to c. 
+0

Salut, J'ai édité ma question et ajouter un cas supplémentaire, pourriez-vous expliquer pour C? Merci beaucoup. – user6142261

+0

@ user6142261 Vérifier ma mise à jour. – BackSlash