2009-05-25 7 views
13

Bene, ho un cliente di classe (nessuna classe base).Come eseguire il cast di tipi di elenchi generici in java?

Ho bisogno di trasmettere da LinkedList a List. C'è un modo pulito per farlo?

Solo per quello che so, ho bisogno di lanciarlo su List. Nessun altro tipo farà. (Sto sviluppando un apparecchio di prova con Slim e FitNesse).


MODIFICA: Ok, penso di dover fornire esempi di codice qui.

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

Quindi, in accordo con le osservazioni di Yuval A, ho finalmente scritto il codice in questo modo. Ma ottengo questo errore:

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 

Quindi, qual è il modo corretto di fare questo cast?

+0

si dovrebbe aver dato esempi di codice dall'inizio , Aggiornerò la mia risposta in un secondo ... –

risposta

25

Non è necessario eseguire il cast. LinkedList implementa List quindi non hai casting da fare qui.

Anche quando si vuole down-cast a un List di Object s si può fare con i generici, come nel codice seguente:

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

Ora, dopo la tua modifica Capisco ciò che si sta cercando di fare , ed è qualcosa che non è possibile, senza creare un nuovo List in questo modo:

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

e ti spiego il perché questo non è possibile altrimenti. Considerate questo:

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??? 

Per ulteriori informazioni, vedere la Sun Java generics tutorial. Spero che questo chiarisca.

+0

Hai perso il mio punto. Considerare: [code] LinkedList ll = someList; List l = ll [/ code]. Va bene? Intendo questo. – jrharshath

+0

Ha fatto ciò che hai detto, ma il problema persiste. Modificato la domanda per aggiungere un esempio di codice e l'errore riscontrato. – jrharshath

+0

Ok, ho capito. Grazie mille :) – jrharshath

0

LinkedList implementa lista, in modo da poter implementare

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

o vuoi lanciare da LinkedList < String> to List < int>? in questo caso devi scegliere ogni singolo elemento e convertirlo in un numero intero.

+0

Voglio convertire da LinkedList a Elenco . Quello (ero solito pensare) dovrebbe essere automatico, coz LinkedList IS_A List e String IS_A Object. Ma oggi ho scoperto che non lo è. :( – jrharshath

-1

L'elenco è un'interfaccia, LinkedList è un'implementazione concreta di tale interfaccia. Per gran parte del tempo una cast implicita funzionerà, assegnerà una LinkedList ad una lista, o la passerà ad una funzione che si aspetta una lista e dovrebbe semplicemente "funzionare".

Un cast esplicito può anche essere eseguito se necessario.

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

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

un cast esplicito non è mai necessario –

+2

non è necessario – Joset

+3

-1 perché questa non è l'idea di un'interfaccia –

1
> public List<Object> getList() 

Perché stai tornando Lista <oggetto>? Si potrebbe anche ritorni List (senza farmaci generici) dal momento che è equivalente, ma renderebbe il seguente codice di lavoro:

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

public List getList() { 
    return theList; 
} 

Casting tra liste con diversi tipi generici è difficile e sembra inutile qui.

Ovviamente si deve ritorneremo tipo List <clienti> ...

0

Si dovrebbe restituire un List<?> dal metodo. Intuitivamente, getList() restituisce un elenco in modo che il chiamante possa recuperare gli elementi all'interno. List<?> (che equivale a List<? extends Object>) consente tale funzionalità. Tuttavia, non sarà possibile inserire nulla tramite l'elenco restituito, poiché ciò non sarebbe sicuro; ma non penso che sia quello di cui hai bisogno comunque.

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

Ecco la mia soluzione orribile per fare casting. Lo so, lo so, non dovrei rilasceremo qualcosa di simile in natura, ma è venuto a portata di mano per lanciare qualsiasi oggetto a qualsiasi tipo:

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

} 

Usage:

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

Ora io vado a pregare gli dei della programmazione per i miei peccati ...

0

appena messo

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

ho fatto questa funzione per questo, brutto ma funziona

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

e 'clazz' è per cosa? – nachokk

0

Se l'elenco è di tipo generico per esempio

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

allora il metodo seguito dovrebbe funzionare

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

Come si usa?

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

come ho detto prima che funziona se l'oggetto contiene elenco generico, questo non funzionerà se si passa un elenco non generico tipo misto di elementi

Problemi correlati