Java中的单链表-get()方法

时间:2018-07-27 10:32:28

标签: java generics

我是Java的新手,正在尝试在Java中实现单链列表。我已经包括了泛型的使用。代码如下所示:

public class LinkedListX<E>{

   Node <E> head;
   int size;

   LinkedListX(){
       head = null;
       size = 0;
   }

   LinkedListX (E e){
       head = new Node(e);
       size = 1;
   }

   void add(E e){
       if (head == null){
           head = new Node (e);
       } else {
           Node current = this.head;
           while (current.next != null){
               current = current.next;
           }
           current.next = new Node(e);
       }
       size++;
   }

   E get (int n){
       if (n > size){
           return null;
       }
       Node current = head;
       for (int i=1;i<n;i++){
           current = current.next;
       }
       return current.e;
   }

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

       Node (E e, Node n){
           this.e = e;
           this.next = n;
       }
       Node (E e) {
           this.e = e;
       }
   }

}

get()方法给出错误消息

  

不兼容的类型,Require:E,在“ return”处找到:java.lang.Object   当前。e

我认为我以错误的方式使用泛型。有人可以让我知道编写此方法的正确方法吗?

谢谢。

6 个答案:

答案 0 :(得分:5)

由于Node是一个内部类,因此它也可以访问外部类的通用参数。而且,您从未为E分配与外部类不同的值。因此,只需从<E>类声明中删除Node

private class Node{
    // the rest
}

答案 1 :(得分:1)

您将Node作为next存储而不使用其通用属性-在许多地方,您应该使用Node<E>而不是Node

基本上,问题是您尝试返回E,但是保存了Node,编译器将其映射到Node<Object>-而Object不是{{ 1}}

答案 2 :(得分:1)

要正确使用泛型,可以更改:

  • get()中:Node current = head;Node<E> current = head;
  • 您所有的new Node()new Node<>()new Node<E>()的快捷方式
  • Node类中也使用<E>

您还可以仅从所有<E>中删除Node(到所有Node类),仍然可以使用E来存储数据)

答案 3 :(得分:1)

您混合了两个问题:

  1. 此行会导致问题(类型不匹配的上方四行):

    Node current = head;
    

    您还必须包含泛型,否则,其原始类型将被识别为Object

    Node<E> current = head;
    

    使用通用对象后,请始终在<>中包含其类型。

  2. 第二件事是,您已经在外部类LinkedListX <E>上使用了泛型,因此其所有内部工作都与E参数一起使用。为此,可以忽略Node类中的泛型。

    private class Node { 
    
        // the implementation
    }
    

    否则,将出现警告投诉:

      

    类型参数E隐藏了类型E

答案 4 :(得分:1)

Node current = head;

上一行是原始类型声明,在这种情况下,'java.lang.Object'是默认的类型变量。

使用参数化类型的节点Node<E> current = head;将解决此问题。

答案 5 :(得分:0)

您的代码有很多Node的原始引用,这会生成很多警告。 get(int n)中的代码段Node是原始代码,不是通用代码,因此Java类型推断算法无法将其标识为E并将其视为对象。请使用以下代码,并检查Eclipse中的区别

public class LinkedListX<E> {

    Node<E> head;
    int size;

    LinkedListX() {
        head = null;
        size = 0;
    }

    LinkedListX(E e) {
        head = new Node<E>(e);
        size = 1;
    }

    void add(E e) {
        if (head == null) {
            head = new Node<E>(e);
        } else {
            Node<E> current = this.head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = new Node<E>(e);
        }
        size++;
    }

    E get(int n) {
        if (n > size) {
            return null;
        }
        Node<E> current = head;
        for (int i = 1; i < n; i++) {
            current = current.next;
        }
        return current.e;
    }

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

        @SuppressWarnings("unused")
        Node(E e, Node<E> n) {
            this.e = e;
            this.next = n;
        }

        Node(E e) {
            this.e = e;
        }
    }
}