有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我在大学学习软件工程,通常我对面向对象编程的基本概念有着相当坚定的理解,但最近我发现自己在一些不容易理解的概念上落后了

一个主要的问题是我不能理解类构造函数;如果我不尽快把它扼杀在萌芽状态的话,我知道这件事会让我垮台

我已经让我的导师解释过了,但他们解释的方式肯定不会让我像往常一样“啊哈”

要帮助您帮助我,请参见以下示例,工作程序(演示链表的使用和操作):

主类:

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>(Main)类中构造函数的用途吗? 在什么情况下应该要求他们


共 (3) 个答案

  1. # 1 楼答案

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

    如果您想要使用值创建新节点,则可以调用public Node(E nVal) {

    如果有nodeValuenextNode,则调用Node(E nVal, Node<E> nextNode)

  2. # 2 楼答案

    您有三个构造函数:

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

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

    第二种方法采用论点(E-nVal);nVal的类型为E,因此实例化的节点对象的类型为Node<;nVal>

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

  3. # 3 楼答案

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

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

    例如,如果数据在构建后永远不会更改,这一点尤其有用。另一个用例是,您将获得的任何对象实例都遵守某些规则——只有在将对象实例提供给他人使用之前,在构造函数内部注意这些规则,您才能安全地做到这一点