2009-05-25 16 views
13

Nun, ich habe eine Klasse Kunde (keine Basisklasse).Wie generiere ich generische Listentypen in Java?

Ich muss von LinkedList auf List umwandeln. Gibt es einen sauberen Weg, dies zu tun?

Nur damit Sie wissen, muss ich es in Liste umwandeln. Kein anderer Typ wird es tun. (Ich entwickle ein Testgerät mit Slim und FitNesse).


EDIT: Okay, ich denke, ich muss hier Codebeispiele geben.

import java.util.*; 
public class CustomerCollection 
{ 
    protected LinkedList<Customer> theList; 

    public CustomerCollection() 
    { 
     theList = new LinkedList<Customer>(); 
    } 

    public void addCustomer(Customer c){ theList.add(c); } 
    public List<Object> getList() 
    { 
     return (List<? extends Object>) theList; 
    } 
} 

So gemäß Yuval A Bemerkungen, ich habe endlich den Code auf diese Weise geschrieben. Aber ich bekomme diesen Fehler:

CustomerCollection.java:31: incompatible types 
found : java.util.List<capture#824 of ? extends java.lang.Object> 
required: java.util.List<java.lang.Object> 
     return (List<? extends Object>)theList; 
      ^
1 error 

Also, was ist der richtige Weg, um diese Besetzung zu tun?

+0

Sie Codebeispiele von Anfang an gegeben haben sollten Ich werde meine Antwort in einer Sekunde aktualisieren ... –

Antwort

25

Sie müssen nicht umwandeln. LinkedList implementiert List so haben Sie hier kein Casting zu tun.

Auch wenn Sie möchten, nach unten Guss auf einen List von Object s können Sie es mit Generika wie im folgenden Code tun:

LinkedList<E> ll = someList; 
List<? extends Object> l = ll; // perfectly fine, no casting needed 

nun nach dem Bearbeiten Ich verstehe, was Sie zu tun versuchen und es ist etwas, das nicht möglich ist, ohne dass ein neues List wie so zu erstellen:

LinkedList<E> ll = someList; 
List<Object> l = new LinkedList<Object>(); 
for (E e : ll) { 
    l.add((Object) e); // need to cast each object specifically 
} 

und ich werde erklären, warum dies sonst nicht möglich ist. Bedenken Sie:

LinkedList<String> ll = new LinkedList<String>(); 
List<Object> l = ll; // ERROR, but suppose this was possible 
l.add((Object) new Integer(5)); // now what? How is an int a String??? 

Weitere Informationen finden Sie in der Sun Java generics tutorial. Hoffe das klärt auf.

+0

Sie haben meinen Punkt verfehlt. Bedenken Sie: [code] LinkedList ll = someList; Liste l = ll [/ code]. Ist das okay? Ich meine das. – jrharshath

+0

Hat getan, was Sie gesagt haben, aber das Problem bleibt bestehen. Bearbeitete die Frage zum Hinzufügen eines Codebeispiels und des aufgetretenen Fehlers. – jrharshath

+0

Okay, habe den Punkt verstanden. Vielen Dank :) – jrharshath

0

LinkedList implementiert Liste, so dass Sie

List<String> list1 = new LinkedList<String>(); 

implementieren Oder wollen Sie von LinkedList < String werfen>> < int zur Liste? In diesem Fall müssen Sie jedes einzelne Element auswählen und in eine Ganzzahl konvertieren.

+0

Ich möchte von LinkedList zu Liste konvertieren. Das (sollte ich denken) sollte automatisch sein, coz LinkedList IS_A List und String IS_A Object. Aber ich habe heute herausgefunden, dass es das nicht ist. :( – jrharshath

-1

List ist eine Schnittstelle, LinkedList ist eine konkrete Implementierung dieser Schnittstelle. Meistens wird eine implizite Umwandlung funktionieren, eine LinkedList einer Liste zuweisen oder sie an eine Funktion übergeben, die eine Liste erwartet und sie sollte einfach 'funktionieren'.

Eine explizite Umwandlung kann bei Bedarf auch durchgeführt werden.

//This is valid 
List<Customer> myList = new LinkedList<Customer>(); 

//Also Valid 
List<Customer> myList = (List<Customer>) new LinkedList<Customer>(); 
+2

eine explizite Umwandlung ist nie notwendig. –

+2

das ist nicht notwendig – Joset

+3

-1 weil dies nicht die Idee einer Schnittstelle ist –

1
> public List<Object> getList() 

Warum kehren Sie Liste <Objekt>? Sie könnten auch Liste zurückkehren (ohne Generika), da dies entspricht aber würde die folgenden Code Arbeit machen:

LinkedList<Customer> theList = new LinkedList<Customer>(); 

public List getList() { 
    return theList; 
} 

zwischen Listen mit verschiedenen generischen Typen Casting heikel ist und scheint hier überflüssig.

Natürlich sollten Sie Typ Liste zurückkehren <Kunden> ...

0

Sie sollten eine List<?> aus Ihrer Methode zurück. Intuitiv gibt getList() eine Liste zurück, damit der Aufrufer die darin enthaltenen Elemente abrufen kann. List<?> (entspricht List<? extends Object>) ermöglicht diese Funktionalität. Sie können jedoch nichts über die zurückgegebene Liste eingeben, da dies nicht typsicher wäre. aber ich glaube nicht, dass du das sowieso brauchst.

public List<?> getList() 
{ 
    return theList; 
} 
17

Hier ist meine schreckliche Lösung für Casting. Ich weiß, ich weiß, ich sollte nicht so etwas wie dieses in die Wildnis veröffentlichen, aber es hat sich als nützlich für jedes Objekt auf jede Art Casting:

public class UnsafeCastUtil { 

    private UnsafeCastUtil(){ /* not instatiable */} 

    /** 
    * Warning! Using this method is a sin against the gods of programming! 
    */ 
    @SuppressWarnings("unchecked") 
    public static <T> T cast(Object o){ 
     return (T)o; 
    } 

} 

Verbrauch:

Cat c = new Cat(); 
Dog d = UnsafeCastUtil.cast(c); 

Jetzt ich werde zu den Göttern der Programmierung für meine Sünden ...

0

gerade setzen

public static List<Object> getList() { 
    List l = test; 
    return l; 
} 
2

ich habe diese Funktion dafür beten, hässlich, aber es funktioniert

public static <T> Collection<T> cast(Collection<? super T> collection, Class<T> clazz){ 
    return (Collection<T>)collection; 
} 
+2

und 'clazz' ist für was? Wird nicht verwendet – nachokk

0

Wenn Ihre Liste eines generischen Typs für zB ist

ArrayList<String> strList = new ArrayList<String>(); strList.add("String1"); Object o = strList;

dann sollten folgende Methode

arbeiten
public <T> List<T> getListObjectInBodyOfType(Class<T> classz, Object body) { 
    if(body instanceof List<?>){ 
     List<?> tempList = (List<?>)body; 
     if(tempList.size() > 0 && tempList.get(0).getClass().equals(classz)){ 
      return (List<T>) body; 
     } 
    } 
    return new ArrayList<T>(); 
} 

Wie es zu benutzen?

List<String> strList1 = getListObjectInBodyOfType(String.class, o); 

wie ich bereits erwähnt, bevor es, wenn das Objekt enthält allgemeine Liste arbeitet, wird dies nicht funktionieren, wenn Sie eine nicht-generische Liste mit gemischtem Typ von Elementen passieren

Verwandte Themen