在LinkedList中使用Generic实现Iterable

时间:2016-10-29 18:11:04

标签: java generics

我想了解在什么情况下应该使用泛型。

假设我想实现一个可迭代的LinkedList。显然,LinkedList应该具有通用的类型参数:

实施1:

public class LinkedList<E>{
    private Node head;

    private class Node{
        private Node next;
        private E e;
    }
}

我的第一个问题:Node应该还有类型参数E吗?也就是说,如果上面的代码写成:

实施2:

public class LinkedList<E>{
    private Node<E> head;

    private class Node<E>{
        private Node<E> next;
        private E e;
    }
}

两个实现都编译良好。我在我的教科书中看到了实施1。因此,似乎实现2有点不必要。

接下来,我想实现Iterable。假设我们坚持实施1,我们将:

实施3:

public class LinkedList<E> implements Iterable<E>{
private Node head;

private class Node{
    private Node next;
    private E e;
}

public Iterator<E> iterator(){
    return new LinkedListIterator();
}

private class LinkedListIterator implements Iterator<E>{
    private Node curr;

    public boolean hasNext(){
        return curr != null;
    }
    public E next(){
        E element = curr.e;
        curr = curr.next;
        return element;
    }
}    

这是我在教科书中看到的标准实施方式。

我的第二个问题:既然我们没有Node的泛型类型,为什么我们也不能不使用泛型类型的Iterable和Iterator呢? e.g:

实施4:

public class LinkedList1<E> implements Iterable{
    private Node head;

    private class Node{
        private Node next;
        private E e;
    }

    public Iterator iterator(){
        return new LinkedListIterator();
    }

    private class LinkedListIterator implements Iterator{
        private Node curr = head;

        public boolean hasNext(){
            return curr != null;
        }
        public E next(){
            E element = curr.e;
            curr = curr.next;
            return element;
        }
    }    
}

1 个答案:

答案 0 :(得分:2)

第一个问题:你是完全正确的,使用泛型为内部Node类是不必要的。这是因为NodeLinkedList<E>的一部分,因此它已经是隐式通用的,不需要为此做更多的事情。如果Node类是LinkedList之外的单独类,则需要将其设为通用类。

编辑:要稍微深入一点,您的Node类实际上属于LinkedList<E>的每个实例。如果您有两个链接列表,则list1.Nodelist2.Node不会被视为同一个类(就像list1.headlist2,head不是同一个变量)。无论list1list2是否具有相同或不同的元素类型,都是如此。但这意味着Node属于已经具有类型参数E的对象,您也可以在E内使用Node(除非您重新声明它,其中如果您只能使用新声明的E,它会掩盖E中的LinkedList

如果您在LinkedList中有静态声明,则上述内容不适用于它们。您已经知道所有实例都共享一个静态字段。如果您声明private static class Node …,则该类将在所有链接列表之间共享。逻辑仍然有效,但您必须声明它是通用的(当您希望它是通用的;与LinkedList之外的类相同)。此外,如果public static void main()中有LinkedList,因为它是静态的,即使是LinkedList也不是通用的,并且如您在评论中所述,如果您从LinkedList实例化Iterable在这里,你应该给出一个类型参数。编辑结束。

第二个问题:正如您所发现的,您需要将类型参数传递给IteratorLinkedList接口。这是因为它们不在您的LinkedListIterator课程范围内,因此不属于您班级的通用范围。另一方面,您的LinkedList非静态类位于LinkedList内,因此是通用的,因为if (Gdx.input.isKeyJustPressed(Input.Keys.A)) player.position.x = player.position.x-moveSpeed; 本身并且不需要声明为通用。