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

标签 java methods constructor class-constructors

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

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

我已经请我的导师解释了,但一定是他们解释的方式才没有让我像平常那样有“啊哈”的时刻。

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

主类:

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 类型。

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

关于java - 难以理解构造函数以及在另一个类中调用它们的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43913610/

相关文章:

class - scala 类中的两组构造函数参数

java - 在 Guice 中构造对象时为字段提供对象

java - 可以在浏览器工具中查看httpservletrequest数据吗?

java - 如何将文件正确添加到 Maven 中的引导类路径?

java - Java中如何调用带有函数输入的方法?

java - 从另一个调用一个构造函数,在 Java 中重载

java - 数组的值发生变化而没有任何命令影响它

java - 使用枚举和 switch 语句来控制方法执行

参数在双括号中的 Ruby 方法

c++ - 使用重载的 >> 运算符调用 CPP 构造函数