2016-04-25 58 views
6

通过作业学习Java迭代器和一般数据结构。我建立了一个双链表(LinkedList),它使用节点(LinkedList $节点),并有一个迭代器(LinkedList $ LinkedListIterator)所有的类都使用泛型。为什么javac错误“(x)不能应用于(y)”,当参数和参数都匹配时发生? (内部类调用外部类方法)

within LinkedListIterator的@Overridden remove()方法我正在使用外部类的方法,即LinkedList类。

我得到以下编译时错误:

./LinkedList.java:170: deleteNode(LinkedList<T>.Node<T>,LinkedList<T>.Node<T>,LinkedList<T>.Node<T>) in LinkedList<T> cannot be applied to (LinkedList<T>.Node<T>,LinkedList<T>.Node<T>,LinkedList<T>.Node<T>) 
     deleteNode(nodeToBeRemoved, next, prev); 

我(原语)的理解是,类型不匹配,但我看不出怎么说也是如此。

这里是我完整的类代码:

import java.util.Iterator; 
import java.util.NoSuchElementException; 
import java.util.ConcurrentModificationException; 


public class LinkedList<T> implements Iterable<T> { 
    private Node<T> sentinel; 
    private long modCount; //apparently no unsigned int's in Java. 

    public LinkedList() { 
     modCount = 0; 
     sentinel = new Node<T>(null); 
     sentinel.setNext(sentinel); 
     sentinel.setPrev(sentinel); 
    } 

    public void append(T t) { 
     /* 
        APPEND: 
         ... 
        [-----] 
        |  | 
        [-1st-] 
        |  | 
     inFront-> [SENTL] 
        |  | <-- [newNode] 
     behind--> [-----] 
        |  | 
        [-----] 
         ... 
     */ 
     Node<T> newNode = new Node<T>(t); 
     Node<T> inFront = sentinel; 
     Node<T> behind = sentinel.prev(); 

     //now actually insert: 
     insertNode(newNode, inFront, behind); 
    } 

    public void prepend(T t) { 
     /* 
        PREPEND: 
         ... 
        [-----] 
        |  | 
     inFront-> [-1st-] 
        |  | <-- [newNode] 
     behind--> [SENTL] 
        |  | 
        [-----] 
        |  | 
        [-----] 
     */ 

     Node<T> newNode = new Node<T>(t); 
     Node<T> behind = sentinel; 
     Node<T> inFront = sentinel.next(); 

     //now actually insert: 
     insertNode(newNode, inFront, behind); 
    } 

    public void removeHead() { 
     /* 
        REMOVE-FIRST: 
         ... 
     inFront --> [-----] 
        |  | 
        [-1st-] <-- *delete* 
        |  | 
     behind ---> [SENTL] 
        |  | 
        [-----] 
        |  | 
        [-----] 
         ... 
     */ 

     Node<T> inFront = sentinel.next().next(); 
     Node<T> behind = sentinel; 
     Node<T> toDelete = sentinel.next(); 

     // now actually delete 
     deleteNode(toDelete, inFront, behind); 
    } 

    private void insertNode(Node<T> newNode, Node<T> inFront, Node<T> behind) { 
     newNode.setNext(inFront); 
     newNode.setPrev(behind); 
     inFront.setPrev(newNode); 
     behind.setNext(newNode); 
     modCount++; 
    } 

    private void deleteNode(Node<T> toDelete, Node<T> inFront, Node<T> behind) { 
     inFront.setPrev(behind); 
     behind.setNext(inFront); 
     toDelete.setNext(null); 
     toDelete.setPrev(null); 
     modCount++; 
    } 

    @Override 
    public Iterator<T> iterator() { 
     return new LinkedListIterator<T>(sentinel); 
    } 






    /* 
     ..:: MyIterator ::.. 
     private inner class 
    */ 
    public class LinkedListIterator<T> implements Iterator<T> { 
     private Node<T> cursor; 
     private Node<T> lastReturned; 
     private long iterModCountPerspective; 

     public LinkedListIterator(Node<T> sentinel) { 
      cursor = sentinel.next(); 
      lastReturned = null; 
      iterModCountPerspective = modCount; 
     } 

     private boolean hasBodhi() { 
      // bodhi: in Buddhism, bodhi is the understanding of the "true nature of things". 
      return (iterModCountPerspective == modCount); 
     } 

     @Override 
     public boolean hasNext() { 
      if (cursor == sentinel) 
       return false; 
      return true; 
     } 

     @Override 
     public T next() { 
      if (!this.hasNext()) { 
       throw new NoSuchElementException(); 
      } else if (!hasBodhi()) { 
       throw new ConcurrentModificationException(); 
      } else { 
       T aux = cursor.data(); 
       lastReturned = cursor; 
       cursor = cursor.next(); 
       return aux; 
      } 
     } 

     @Override 
     public void remove() { 
      //check we're allowed to remove: 
      if (lastReturned == null) { 
       throw new IllegalStateException(); 
      } 
      if (!hasBodhi()) { 
       throw new ConcurrentModificationException(); 
      } 

      //setup vars to perform deletion: 
      Node<T> nodeToBeRemoved = lastReturned; 
      Node<T> next = nodeToBeRemoved.next(); 
      Node<T> prev = nodeToBeRemoved.prev(); 

      // now delete 
      deleteNode(nodeToBeRemoved, next, prev); 
      iterModCountPerspective++; 

      //now setup vars for exit: 
      cursor = next; 
      lastReturned = null; // illegal to remove yet-again before first calling next() 
     } 
    } 





    /*   ..:: Node ::.. 
     private, compositional inner class 

     Interface: 
     void  setNext(Node n) // change the Node in front of this Node 
     void  setPrev(Node p) // change the Node behind this Node 
     Node  next()   // returns the Node in front of this Node 
     Node  prev()   // returns the Node behind this Node 
     T  data()   // returns the data stored inside this Node 
    */ 
    private class Node<T> { 
     private T data; 
     private Node<T> next; 
     private Node<T> prev; 

     public Node(T d) { 
      data = d; 
      next = null; 
      prev = null; 
     } 

     /* 
      METHOD setNext(Node<T> n) 

       This method takes the parameter Node 
       passed-in and puts it in front of this 
       Node. 

       input - Node n 
       output - none 

       eg: node4.setNext(node5); 
      */ 
     public void setNext(Node<T> n) { 
      next = n; 
     } 


     /* 
      METHOD setPrev(Node<T> n) 

       This method takes the parameter Node 
       passed-in and puts it behind of this 
       Node. 

       input - Node p 
       output - none 

       eg: node5.setPrev(node4); 
      */ 
     public void setPrev(Node<T> p) { 
      prev = p; 
     } 



     /* 
      METHOD next() 

       This method returns the Node in 
       front of this Node. 

       input - none 
       output - Node infront of this (this.next) 

       eg: Node nodeInFrontOfNode4 = node4.next(); 
      */ 
     public Node<T> next() { 
      return next; 
     } 



     /* 
      METHOD prev() 

       This method returns the Node 
       behind of this Node. 

       input - none 
       output - Node behind of this (this.prev) 

       eg: Node nodeBehindOfNode4 = node4.prev(); 
      */ 
     public Node<T> prev() { 
      return prev; 
     } 



     /* 
      METHOD data() 

       This method returns the data 
       inside of this Node. 

       input - none 
       output - Data inside of this Node 

       eg: PlanarShape shape4 = node4.data(); 
      */ 
     public T data() { 
      return data; 
     } 
    } 

} 

比较-SCI的学生,第一次海报。 谢谢所有的SO大师。你已经帮助我的同事和我很多次

+1

欢迎来到StackOverflow!你的问题的描述非常清楚,但是你也发布了大量的代码。下次尝试将代码范围缩小到一个会导致相同问题的最小示例。 –

+2

通常,这意味着您有两件事实际上不同,但名称相同。在这种情况下,我一眼就可以看到它不应该是私人类节点而是私人类节点。 –

+3

同样,'public class LinkedListIterator implements Iterator '应该是'public class LinkedListIterator implements Iterator '。目前,您正在'LinkedListIterator'和'Node'类上定义一个新的泛型类型。请注意,尽管使用了“T”,但所有三个“T”(包括“LinkedList ”中的一个)都不相同。 –

回答

2

发生这种情况,因为你正在定义3种不同类型的参数。当你声明一个类为:

class X<T> {} 

...你定义一个新的类型参数T,这是否是一个内部类或外部类。因此,在以下情况下:

class X<T> { 
    class Y<T> { 
    } 
} 

这两个T's是不同的。你可以做这样的事情:

X<String> x = new X<String>(); 
Y<Double> y = x.new Y<Double>(); 

因此,考虑在这里的情况:

class X<T> { 
    public void helloThere(T obj) { } 

    class Y<T> { 
     // Ignore any syntactical error about method calling. 
     public void callHelloThere(T obj) { 
      helloThere(obj); 
     } 
    } 
} 

为将肯定是不行的:

y.callHelloThere(2.5); 

因为那样的话,你传递一个Double键入接受String的方法,因为您实例化了X<String>

这与您在示例中面临的情况相同。

解决方案?将class Y<T>更改为class Y,然后你就完成了。

+1

不错,我不知道'T!= T' – Antoniossss

+1

我对泛型的理解是低于标准的。谢谢你,罗希特。非常简洁的答案和一个很好的例子。 –

相关问题