2016-04-25 60 views
6

Ev ödevi aracılığıyla Java yineleyicileri ve genel veri yapıları hakkında bilgi edinin."(x) javac hatası neden (y) 'ye uygulanamaz, her iki parametre ve bağımsız değişken eşleştiğinde ne olur? (iç sınıf arama dış sınıf yöntemi)

Nodes (LinkedList $ Node) kullanan ve bir Iterator (LinkedList $ LinkedListIterator) kullanan iki bağlantılı bir liste (LinkedList) oluşturdum. Tüm sınıflar jeneriklerden yararlanıyor.

LinkedListIterator'ın @Overridden remove() yöntemi içinde Dış sınıfın, yani LinkedList sınıfının bir yöntemini kullanıyorum.

./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); 

Benim (ilkel) anlayışı ancak o kadar nasıl göremez, türleri maç kalmamasıdır:

aşağıdaki derleme zamanı hatası alıyorum.

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; 
     } 
    } 

} 

Comp-bilim öğrencisi ilk kez posteri:

İşte benim tam sınıf kodudur. Tüm SO gurular için teşekkür ederiz. Akranlarıma ve birçok kez

+1

StackOverflow'a Hoş Geldiniz! Sorunuzun açıklaması çok açık, ancak bununla birlikte büyük miktarda kod da yayınladınız. Bir dahaki sefere, kodu aynı soruna yol açacak minimal bir örneğe daraltmaya çalışın. –

+2

Genellikle bu, aslında farklı ancak aynı adlı iki şeyiniz olduğu anlamına gelir. Bu durumda, bir bakışta "özel sınıf Node " değil, "özel sınıf Düğümü" olması gerektiğini görebiliyorum. –

+3

Benzer şekilde, public class LinkedListIterator Iterator 'yi uygular; public class LinkedListIterator Iterator ' uygular. Şu anda hem "LinkedListIterator" hem de "Node" sınıfında yeni bir jenerik tür tanımlıyorsunuz.'T' kullanılsa bile, tüm üç 'T'nin' (LinkedList 'içinde bulunanlar dahil) farklı olduğunu unutmayın. –

cevap

2

'a yardımcı oldunuz. Bu oluyor, çünkü burada 3 farklı tip parametresi tanımlıyorsunuz. Eğer bir sınıf bildirmek zaman:

class X<T> {} 

... bunu bir iç sınıf veya dış sınıf olsun, yeni bir tür parametresi T tanımlar. Yani, aşağıda senaryoda:

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

hem T's farklıdır. Böyle bir şey yapabilirsiniz:

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); 
     } 
    } 
} 

için kesinlikle çalışmaz:: Çünkü o zaman, bir Double geçiyoruz

y.callHelloThere(2.5); 

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

Yani, burada bir dava düşünün X<String>'u başlattığınız için String kabul eden bir yönteme yazın.

Bu, örneğinizde karşılaştığınız aynı senaryodur.

Çözüm? class Y<T>'u class Y olarak değiştirin ve hepiniz ayarlandınız.

+1

Güzel, bunu bilmiyordum 'T! = T' – Antoniossss

+1

Jenerik bilgilerim alt par. Sağol Rohit. Çok özlü cevap ve harika bir örnek. –