内部操作的静态方法 class

Static methods for operations on inner class

我正在学习 算法第四版 (Sedgewick),我对一些链表练习感到困惑,这些练习似乎要求为非静态节点。例如,

1.3.27 Write a method max() that takes a reference to the first node in a linked list as argument and returns the value of the maximum key in the list. Assume that all keys are positive integers, and return 0 if the list is empty.

1.3.31 Implement a nested class DoubleNode for building doubly-linked lists, where each node contains a reference to the item preceding it and the item following it in the list (null if there is no such item). Then implement static methods for the following tasks: insert at the beginning, insert at the end, remove from the beginning, remove from the end, insert before a given node, insert after a given node, and remove a given node.

据我了解(并由 SO 回答 here and here 确认)这是不可能的。正如预期的那样,如果我尝试在 superclass:

中编写静态方法,Eclipse 会出错
public class DoublyLinkedList<Item> {

    public static void insertStart(DoubleNode first) {
        // implementation
    }

    private class DoubleNode {
        Item item;
        DoubleNode next;
        DoubleNode previous;

    }
}

(给出错误Cannot make a static reference to the non-static type DoubleNode);或者在内部 class:

public class DoublyLinkedList<Item> {

    private class DoubleNode {
        Item item;
        DoubleNode next;
        DoubleNode previous;

        public static void insertStart(DoubleNode first) {
            // implementation
        }
    }
}

(给出错误 The method insertStart cannot be declared static; static methods can only be declared in a static or top level type)。

我可以为 DoublyLinkedList class 编写所需的方法作为 实例方法 ,这对我来说似乎最自然。

但是,我觉得我可能在这里错过了一些重要的事情。作者明确指出方法应该是静态的,并且还建议将对第一个节点的引用作为参数(这对于实例方法来说是不必要的,因为 class 将为第一个节点提供一个实例变量) .我错过了什么?

您可以将嵌套的 class 设为 static。您将失去拥有封闭父 class 实例的约束,但它将允许您从静态方法对 DoubleNodes 进行操作:

// This will compile
public class DoublyLinkedList<Item> {

    public static <T> void insertStart(DoublyLinkedList<T> list, DoubleNode<T> first) {
        // implementation
    }

    private static class DoubleNode<E> {
        E item;
        DoubleNode<E> next;
        DoubleNode<E> previous;

    }
}

这里需要注意两件事:如您所见,当使内部 class 静态化时,您需要为其提供自己的类型参数(在本例中为 E)。在你的代码中你不需要这样做,因为任何 DoubleNode 实例都保证有一个包含 DoublyLinkedList 的实例,它已经决定了 Item 是什么。

其次,您需要为静态方法引入一个类型参数 ("<T>"),这样您就可以为两个参数强制使用相同的泛型类型。您也可以这样做并侥幸逃脱 :

public static void insertStart(DoublyLinkedList<?> list, DoubleNode<?> first) {
    ...
}

如果您想知道,这也是在 JDK 的 LinkedList 实现中完成的方式:

// Source : Oracle JDK 1.7.0_67 lib - inside LinkedList class
private static class Node<E> {
     E item;
     Node<E> next;
     Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
       this.item = element;
       this.next = next;
       this.prev = prev;
    }
}

作为旁注,我同意将这些方法编写为实例成员更为自然;这就是它通常在 OOP 库中完成的方式。我没有 Sedgewick 的书,但看起来他正试图同时教你嵌套 class 操作和列表实现 ;)