2009-05-25 12 views
13

Bueno, tengo un cliente de clase (sin clase base).Cómo lanzar tipos de lista genéricos en Java?

Necesito transmitir desde LinkedList a List. ¿Hay alguna manera limpia de hacer esto?

Para que lo sepas, necesito echarlo a la lista. Ningún otro tipo servirá. (Estoy desarrollando un dispositivo de prueba usando Slim y FitNesse).


EDIT: Bien, creo que necesito dar ejemplos de código aquí.

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

De acuerdo con las observaciones de Yuval A, finalmente he escrito el código de esta manera. Pero me sale este error:

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 

Entonces, ¿cuál es la forma correcta de hacer este elenco?

+0

que debería haber dado ejemplos de código desde el principio , Actualizaré mi respuesta en un segundo ... –

Respuesta

25

No es necesario que lances. LinkedList implementa List por lo que no tiene fundición para hacer aquí.

Incluso cuando se quiere-arrojado a un List de Object s lo puede hacer con los genéricos, como en el siguiente código:

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

Ahora, después de su edición entiendo lo que está tratando de hacer , y es algo que no es posible, sin crear un nuevo List así:

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

y voy a explicar por qué esto no es posible de otro modo. Considere esto:

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

Para obtener más información, consulte la Sun Java generics tutorial. Espero que esto aclare.

+0

Olvidaste mi punto. Considere: [código] LinkedList ll = someList; Lista l = ll [/ code]. ¿Esta bien? Quiero decir esto. – jrharshath

+0

Hizo lo que dijo, pero el problema persiste. Editó la pregunta para agregar el ejemplo de código y el error encontrado. – jrharshath

+0

De acuerdo, entiendo el punto. Muchas gracias :) – jrharshath

0

LinkedList implementa la lista, por lo que puede poner en práctica

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

o quieres enviar contenido desde ListaEnlazada < String> a la lista < int>? en este caso, debe elegir cada elemento y convertirlo en un número entero.

+0

Quiero convertir de LinkedList a la lista . Eso (yo solía pensar) debería ser automático, co LinkedList IS_A List, y String IS_A Object. Pero descubrí hoy que no es así. :( – jrharshath

-1

La lista es una interfaz, LinkedList es una implementación concreta de esa interfaz. La mayoría de las veces un elenco implícito funcionará, se asignará una lista vinculada a una lista, o se pasará a una función que espera una lista y simplemente 'funcionará'.

También se puede realizar un lanzamiento explícito si es necesario.

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

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

un lanzamiento explícito nunca es necesario. –

+2

esto no es necesario – Joset

+3

-1 porque esta no es la idea de una interfaz –

1
> public List<Object> getList() 

¿Por qué estás devolviendo Lista <objeto>? Es lo mismo que la lista (sin genéricos) regrese ya que es equivalente, pero haría que el trabajo siguiente código:

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

public List getList() { 
    return theList; 
} 

Conversiones entre listas con diferentes tipos genéricos es complicado y parece innecesaria aquí.

Por supuesto que se debe regresando tipo Lista <cliente> ...

0

Usted debe devolver un List<?> de su método. Intuitivamente, getList() devuelve una lista para que la persona que llama pueda recuperar los elementos dentro. List<?> (que es equivalente a List<? extends Object>) permite esa funcionalidad. Sin embargo, no podrá poner nada en él a través de la lista devuelta, porque eso no sería seguro; pero no creo que eso sea lo que necesitas de todos modos.

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

Aquí está mi solución horrible para hacer casting. Lo sé, lo sé, yo no debería estar liberando algo como esto en la naturaleza, pero ha sido muy útil para la fundición de cualquier objeto de cualquier 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; 
    } 

} 

Uso:

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

Ahora voy a rezar a los dioses de la programación por mis pecados ...

0

sólo hay que poner

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

hice esta función para la que, feo, pero funciona

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

y 'clazz' es para qué? No se usa – nachokk

0

Si la lista es de un tipo genérico de ejemplo

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

continuación Siguiendo método debería funcionar

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

Cómo se utiliza?

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

como he mencionado antes de que funciona si el objeto contiene lista genérica, esto no funcionará si se pasa una lista no genérico con tipo mixto de elementos