2017-05-11 40 views
0

我在大學學習軟件工程,並且我通常對面向對象編程的基本概念有非常牢固的把握,但最近我發現自己落後了在一些不容易理解的概念上。理解構造函數的問題以及在另一個類中調用它們的原因

一個主要問題是我無法繞過類構造函數;如果我不盡快將它扼殺在萌芽狀態,我知道的事情將會是我的倒臺。

我已經請我的導師解釋,但一定是他們解釋它的方式,只是沒有讓我有我通常做的「啊哈」的時刻。

爲了幫助你幫我,看看下面的例子,工作方案(示範鏈表的使用和操作):

主類:

package root; 

public class Node<E> { 
    private E nodeValue; 
    private Node<E> next; 

    public static void main (String[] args) { 
     try { 
      // Example 1: Create an empty list and print it. 
      SinglyLinkedList<Integer> list1 = new SinglyLinkedList<Integer>(); 
      System.out.println("Example 1: Create an empty list."); 
      System.out.println(list1.printList()); 

      // ---------------------------------------------------------- 
      // Example 2: Create a list of 1 integer (1) using InsertNodeToTail. 
      System.out.println("\nExample 2: Create a list of 1 integer using InsertNodeToTail."); 
      SinglyLinkedList<Integer> list2 = new SinglyLinkedList<Integer>(); 
      System.out.println("Before: " + list2.printList()); 
      list2.insertNodeToTail(1); 
      System.out.println("After: " + list2.printList()); 

      // ---------------------------------------------------------- 
      // Example 3: Create a list of 1 integer (1) using InsertNodeToHead. 
      System.out.println("\nExample 3: Create a list of 1 integer using InsertNodeToHead."); 
      SinglyLinkedList list3 = new SinglyLinkedList(); 
      System.out.println("Before: " + list3.printList()); 
      list3.insertNodeToHead(1); 
      System.out.println("After: " + list3.printList()); 

      // ---------------------------------------------------------- 
      // Example 4: Create a list of 5 integers (1, 3, 5, 7, and 9) 
      // using InsertNodeToTail. Output: 1->3->5->7->9 
      System.out.println("\nExample 4: Create list 1->3->5->7->9 using InsertNodeToTail."); 
      // Create an array of 5 integers 
      int[] array4 = { 1, 3, 5, 7, 9 }; 
      // Create the head node 
      SinglyLinkedList<Integer> list4 = new SinglyLinkedList<Integer>(); 
      System.out.println("Before: " + list4.printList()); 
      // Insert nodes 
      for (int i = 0; i < array4.length; i++) 
       list4.insertNodeToTail(array4[i]); 
      System.out.println("After: " + list4.printList()); 

      // ---------------------------------------------------------- 
      // Example 5: Create a list of 5 integers (1, 3, 5, 7, and 9) 
      // using InsertNodeToHead. Output: 1->3->5->7->9 
      System.out.println("\nExample 5: Create list 1->3->5->7->9 using InsertNodeToHead."); 
      // Create an array of 5 integers 
      int[] array5 = { 1, 3, 5, 7, 9 }; 
      // Create the head node 
      SinglyLinkedList<Integer> list5 = new SinglyLinkedList<Integer>(); 
      System.out.println("Before: " + list5.printList()); 
      // Insert nodes 
      for (int i = array5.length - 1; i >= 0; i--) 
       list5.insertNodeToHead(array5[i]); 
      System.out.println("After: " + list5.printList()); 

      // ---------------------------------------------------------- 
      // Example 6: Insert new node before a current node 
      System.out.println("\nExample 6: Insert node 0 before node 1."); 
      // Use list2, insert node 0 before node 1 
      System.out.println("Before: " + list2.printList()); 
      list2.insertNodeBefore(0, 1); 
      System.out.println("After: " + list2.printList()); 

      // ---------------------------------------------------------- 
      // Example 7: Insert new node before a current node 
      System.out.println("\nExample 7: Insert node 4 before node 5."); 
      // Use list4, insert node 4 before node 5 
      System.out.println("Before: " + list4.printList()); 
      list4.insertNodeBefore(4, 5); 
      System.out.println("After: " + list4.printList()); 

      // ---------------------------------------------------------- 
      // Example 8: Insert new node after a current node 
      System.out.println("\nExample 8: Insert node 2 after node 1."); 
      // Use list2, insert node 2 after node 1 
      System.out.println("Before: " + list2.printList()); 
      list2.insertNodeAfter(2, 1); 
      System.out.println("After: " + list2.printList()); 

      // ---------------------------------------------------------- 
      // Example 9: Insert new node after a current node 
      System.out.println("\nExample 9: Insert node 10 after node 9."); 
      // Use list4, insert node 10 after node 9 
      System.out.println("Before: " + list4.printList()); 
      list4.insertNodeAfter(10, 9); 
      System.out.println("After: " + list4.printList()); 

      // ---------------------------------------------------------- 
      // Example 10: Remove node if node value is given 
      System.out.println("\nExample 10: Remove node 10."); 
      // Use list4, remove node 10 
      System.out.println("Before: " + list4.printList()); 
      list4.remove(10); 
      System.out.println("After: " + list4.printList()); 

      // ---------------------------------------------------------- 
      // Example 11: Remove node that is not in the list 
      System.out.println("\nExample 11: Remove node 100."); 
      // Use list4, remove node 100 
      System.out.println("Before: " + list4.printList()); 
      list4.remove(100); 
      System.out.println("After: " + list4.printList()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    public Node() { 

    } 

    public Node(E nVal) { 
     nodeValue = nVal; 
    } 

    public Node(E nVal, Node<E> nextNode) { 
     nodeValue = nVal; 
     next = nextNode; 
    } 

    public E getNodeValue() { 
     return nodeValue; 
    } 

    public void setNodeValue (E nVal) { 
     nodeValue = nVal; 
    } 

    public Node<E> getNext() { 
     return next; 
    } 

    public void setNext (Node<E> n) { 
     next = n; 
    } 
} 

子類:

package root; 

import java.io.*; 

public class SinglyLinkedList<E> { 

    private Node<E> head; 

    // Create an empty list 
    public SinglyLinkedList() { 
     head = null; 
    } 

    // Access to the entire linked list (read only) 
    public Node<E> getHead() { 
     return head; 
    } 

    // Insert a node with node value = nVal as the last node 
    public void insertNodeToTail(E nVal) { 
     Node<E> lastNode = new Node<E>(); 
     lastNode.setNodeValue(nVal); 
     if (head == null) { 
      head = lastNode; 
      return; 
     } 

     Node<E> curr = head; 
     while (curr.getNext() != null) { 
      curr = curr.getNext(); 
     } 
     curr.setNext(lastNode); 
    } 

    // Insert a node with node value = nval as the first node 
    public void insertNodeToHead(E nVal) { 
     Node<E> newHead = new Node<E>(); 
     newHead.setNodeValue(nVal); 
     newHead.setNext(head); 
     head = newHead; 
    } 

    // Insert new node nVal to the list before current node curVal 
    public void insertNodeBefore(E nVal, E curVal) { 
     Node<E> newNode = new Node<E>(nVal); 

     Node<E> curr = head; 
     Node<E> prev = null; 

     if (head.getNodeValue() == curVal) { 
      newNode.setNext(head); 
      head = newNode; 
      return; 
     } 

     // scan until locate node or come to end of list 
     while (curr != null) { 
      // have a match 
      if (curr.getNodeValue() == curVal) { 
       // insert node 
       newNode.setNext(curr); 
       prev.setNext(newNode); 
       break; 
      } else { 
       // advanced curr and prev 
       prev = curr; 
       curr = curr.getNext(); 
      } 
     } 
    } 

    // Insert new node nVal to the list after current node curVal 
    public void insertNodeAfter(E nVal, E curVal) { 
     Node<E> newNode = new Node<E>(); 
     newNode.setNodeValue(nVal); 

     Node<E> curr = head.getNext(); 
     Node<E> prev = head; 

     //scan until locate a node or come to the end of the list 
     while (prev != null) { 
      //have a match 
      if (prev.getNodeValue().equals(curVal)) { 
       //insert node 
       newNode.setNext(curr); 
       prev.setNext(newNode); 
       break; 
      } else { 
       //advance curr and prev 
       prev = curr; 
       curr = curr.getNext(); 
      } 
     } 
    } 

    // Remove the node containing item nVal 
    public void remove(E nVal) throws IOException { 
     if (head == null) { 
      throw new IOException("List empty!"); 
     } else { 

      Node<E> curr = head; 
      Node<E> prev = null; 

      // becomes true if we locate target 
      boolean foundItem = false; 
      // scan until locate nodeVal or come to end of list 

      while (curr != null && !foundItem) { 
       // have a match 
       if (curr.getNodeValue() == nVal) { 
        // if current node is the first node 
        // remove first node by moving head to next node 
        if (prev == null) { 
         head = head.getNext(); 
        } else { // erase intermediate node 
         prev.setNext(curr.getNext()); 
        } 
        foundItem = true; 
       } else { 
        // advanced curr and prev 
        prev = curr; 
        curr = curr.getNext(); 
       } 
      } 
     } 
    } 

    public String printList() { 
     String outputList = ""; 
     Node<E> temp = head; 

     if (temp == null) { 
      return "List empty!"; 
     }   
     do { 
      // Print head node value 
      outputList += temp.getNodeValue().toString(); 
      // Move to next node 
      temp = temp.getNext(); 
      // if next node is not empty, print -> 
      // else print end of line then break the loop 
      if (temp != null) { 
       outputList += "->"; 
      } else { 
       break; 
      } 
     } while (true); 
      // the loop terminates itself when it reaches to 
      // end of the list 
      return outputList; 
    } 
} 

任何人都可以解釋什麼構造函數的目的在t他的通用Node<E>(主)班是? 他們應該在什麼情況下被要求?

+0

由於節點類定義爲泛型,因此它可以接受字符串,整型,用戶定義的類,如Person/Student。如果您仔細查看它在Main類中的元素,並將其添加到鏈表中,那麼它還會用於創建該特定類型的鏈表。 (基本上,你在這個鏈表上執行的所有動作都是以remove()/ insert()/ print()的形式存在的,並且這些值是從構造函數中分配的) –

+0

用法 - 查看insertNodeAfter (E val,E curVal)方法。在那裏的第一行中,用空構造函數創建一個新節點,然後設置節點值。這是一個你更願意使用其他構造函數的例子。 – Terje

+0

在這裏在StackOverflow長期和非技術性的介紹像你張貼的是不鼓勵。請嘗試堅持這個問題,提出一個明確的問題,並提供必要的背景(代碼,輸出,示例)。 –

回答

0

如果您要創建新節點並且沒有任何數據,則可以致電public Node() {

public Node(E nVal) {如果你用魔杖創建一個帶有值的新節點,可以調用它。

Node(E nVal, Node<E> nextNode)被調用時,如果你有nodeValuenextNode

0

你有三種構造函數:

public Node() { 

} 

public Node(E nVal) { 
    nodeValue = nVal; 
} 

public Node(E nVal, Node<E> nextNode) { 
    nodeValue = nVal; 
    next = nextNode; 
} 

第一個是默認的構造函數,沒有參數。它實例化一個類對象節點。

第二個參數(E nVal); nVal是E類型的,因此實例化的節點對象將是類型節點<nVal>。

第三個構造函數接受兩個參數(E nVal,Node nextNode);它與第二個構造函數的作用相同,並且它將列表中的下一個節點設置爲nextNode;然後將該參考存儲在下一個實例化對象的變量中。

0

每個構造函數創建一個新的對象實例。默認的構造函數不接受任何參數,如果你不提供任何你自己的代碼,也不會對新對象產生任何影響。

爲方便起見,通常會在構造函數中創建帶參數和/或帶有代碼的構造函數,以便返回的新對象實例預先配置一些數據。

例如,如果數據在構建後永遠不會改變,那麼這尤其有用。另一個用例是任何你會得到的對象實例都遵守某些規則 - 在給對象實例使用之前,你只能通過在構造函數中關注這些規則來安全地做到這一點。

相關問題