2016-06-29 19 views
0

Ich habe zwei Klassen erstellt, Eltern und Kind. My Parent-Klasse implementiert Vergleichbare Schnittstelle als „Klasseneltern implementiert Comparable“Verwenden von Platzhaltern mit Type-Parameter Benötigt zusätzliches Casting

ich auch eine Methode geschrieben haben, die die maximale Element einer Liste zurückgibt, hier habe ich? Super-T-Wildcard, um jede Child-Klasse des Elternteils zu akzeptieren.

Der folgende Code funktioniert gut für eine Liste untergeordneter Objekte.

public static <T extends Comparable<? super T>> T max(List <T> list){ 
    Iterator< T> itr = list.iterator(); // line xx 
    T result = itr.next(); 
    T temp ; 
    while(itr.hasNext()){ 
     temp = itr.next(); 
     if(temp.compareTo(result) > 0) 
      result = temp ; 
    } 
    return result ; 
} 

Aber wenn ich die Art Proto von max Methode zu ändern, indem Sie < jede Liste der Unterart von T zu akzeptieren? erweitert T> dann kompiliert der obige Code nicht.

Compliation Fehler ist: kann nicht von Iterator konvertieren

auf Ändern Linie xx Iterator "Iterator < T> itr = (Iterator) list.iterator();" Der Code funktioniert mit <? erweitert T> Argument.

public static <T extends Comparable<? super T>> T max(List <? extends T> list){ 
    Iterator< T> itr = (Iterator<T>) list.iterator(); // works fine 
    Iterator< T> itr1 = list.iterator();   // generates compile error . 
    T result = itr.next(); 
    T temp ; 
    while(itr.hasNext()){ 
     temp = itr.next(); 
     if(temp.compareTo(result) > 0) 
      result = temp ; 
    } 
    return result ; 
} 

Ich bekomme es nicht, warum ich kompilieren Zeit Fehler geworfen wird.

Code Complete folgt als:

package Generics; 

import java.util.*; 

public class WildCard { 
public static void main(String[] args) { 
    List<Child> cList = Arrays.asList(new Child("c1"),new Child("c3"),new Child("c2")); 
    System.out.println(max(cList)); 
} 

public static <T extends Comparable<? super T>> T max(List <? extends T> list){ 
    Iterator< T> itr = (Iterator<T>) list.iterator(); 
    T result = itr.next(); 
    T temp ; 
    while(itr.hasNext()){ 
     temp = itr.next(); 
     if(temp.compareTo(result) > 0) 
      result = temp ; 
    } 
    return result ; 
} 
} 
class Parent implements Comparable<Parent>{ 
    private String val ; 
    public Parent(String val){ 
     this.val = val ; 
    } 
    @Override 
    public int compareTo(Parent o) { 
     // TODO Auto-generated method stub 
     return this.val.compareTo(o.val); 
    } 
    public String toString(){ 
     return val ; 
    } 
} 
class Child extends Parent{ 

    public Child(String val) { 
     super(val); 
    } 

} 

Meine Zweifel selbst ist, wenn ich nicht wurde mit? erweitert T in Funktion Argument, Ich konnte die Subtypen akzeptieren und ich brauchte kein Casting. Aber warum, wenn ich diese Syntax ändere, brauche ich Casting?

+0

Ich habe keine Antwort, aber ich habe zwei Techniken, mit denen Sie die Besetzung vermeiden können. Eine for-each-Schleife benötigt keine Besetzung, Sie können also 'for (T t: list)' verwenden. Sie verwenden auch einen Platzhalter im Iterator, um eine Umwandlung zu vermeiden: 'Iterator itr = list.iterator();'. – DavidS

Antwort

0

Da Sie eine List<? extends T> haben, sollten Sie eine Iterator<? extends T> verwenden:

Iterator<? extends T> itr = list.iterator(); 

Und Iterator ist ein Hersteller von T sowieso, also nach der PECS-Regel (Producer extends, Consumer super), so ist es natürlich, dass Iterator sollte mit extends sowieso.