难以理解构造函数以及在另一个类中调用它们的原因



我在大学学习软件工程,我通常已经非常牢固地掌握了面向对象编程的基本概念,但最近我发现自己在一些不那么容易理解的概念上落后了。

一个主要问题是我无法理解类构造函数;我知道如果我不尽快将其扼杀在萌芽状态,这将是我的失败。

我已经让我的导师解释它,但一定是他们的解释方式并没有让我有我通常做的"啊哈"时刻。

为了帮助您帮助我,请参阅下面的示例,工作程序(演示链表的使用和操作(:

主类:

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;
    }
}

谁能解释泛型Node<E>(主(类中构造函数的用途是什么?在什么情况下应该要求他们?

您有三个构造函数:

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

第一个是默认构造函数,不带任何参数。它实例化类节点的对象。

第二个采用参数(E nVal(;nVal是E类型,因此实例化的Node-Object将是Node类型。

第三个构造函数有两个参数(E nVal,Node nextNode(;它与第二个构造函数执行相同的操作,并且设置列表中的下一个节点nextNode;然后此引用存储在实例化对象的下一个变量中。

如果要

创建新节点并且没有任何数据,可以调用public Node() {

如果您使用魔杖创建一个具有值的新节点,则可以调用public Node(E nVal) {

Node(E nVal, Node<E> nextNode)被称为,如果你有nodeValuenextNode

每个构造函数创建一个新的对象实例。默认构造函数不接受任何参数,如果您不提供任何自己的代码,也不会对新对象执行任何操作。

为了方便起见,通常使用构造函数中的参数和/或代码创建构造函数,以便返回的新对象实例预先配置了一些数据。

例如,如果数据在构建后永远不会更改,则此功能特别有用。另一个用例是,你将得到的任何对象实例都遵守某些规则 - 只有在将对象实例交给使用之前,您只能在构造函数中处理这些规则来安全地做到这一点。

最新更新