2010-11-26 30 views
30

Quiero convertir List<String> en List<Object>.Cómo convertir la lista <String> en la lista <Object>

Uno de los métodos existentes es devolver List<String> y quiero convertirlo a List<Object>. ¿Hay alguna forma directa en Java que no sea iterar y convertir elemento por elemento?

+4

'String' es' Objeto' ¿por qué lo necesitas? – khachik

+4

Es posible que deba pasar la lista a una función que espera una 'Lista ' –

+8

¿Qué está tratando de hacer exactamente? Debido a la borradura de tipo, una lista es una lista . Si hay un método que tiene que tomar una lista , ese método se debe modificar a List .Si no tienes el control de ese método, entonces sigue cualquiera de las siguientes respuestas. –

Respuesta

57

Pasar el List<String> como parámetro al constructor de un nuevo ArrayList<Object>.

List<Object> objectList = new ArrayList<Object>(stringList); 

Cualquier Collection se puede pasar como un argumento para el constructor, siempre que su tipo se extiende el tipo de la ArrayList, como String extiende Object. El constructor toma un Collection, pero List es una subinterfaz de Collection, por lo que solo puede usar el List<String>.

+1

Esto construye objetos innecesarios y puede, si se trata de una gran lista, ocupar mucha memoria. Solo echalo. –

+0

Lee mi comentario sobre tu respuesta. Lanzarlo es la solución incorrecta. Esta respuesta no merece un voto negativo. –

+0

Claro. Eliminaré el voto a favor (6 minutos o lo edito). Pero el mío tampoco se lo merece. –

3

Esto es bastante ineficiente, pero al menos no tener que escribir mucho código ~

List<String> stringList = new ArrayList<String>(); 
List<Object> objectList = Arrays.asList(stringList.toArray()); 
+0

Tks. Creo que esto no creará una nueva ArrayList en la memoria, solo convertirá la lista de cadenas original a List . – Alexs

+0

@Alex No crea una nueva ArrayList, pero crea una implementación de Lista privada interna e inmodificable, que se parece bastante a ArrayList. El efecto es muy similar, pero tendrá problemas si necesita agregar un nuevo elemento a esa lista. Además, la memoria que "piensa" que está guardando se está utilizando para crear la nueva matriz después de: 'stringList.toArray()' una nueva matriz asignada se crea después de eso. – OscarRyz

13

Cualquier colección de Java es solo una colección de objetos, ya sea de cadena u otra. El argumento tipo es solo azúcar. Dependiendo de la situación, como tratar con listas muy grandes, es posible que solo desee convertirlo, obviamente arriesgándose a mezclar dos tipos diferentes de objetos en la misma lista.

List<Object> objectList = (List)stringList; 

Y poner un @SuppressWarning para deshacerse de desagradables ...

+2

-1 Esta es una forma pobre de manejarlo. –

+3

Realmente no lo es. ¿Por qué construirías nuevas colecciones cuando ya tienes lo que necesitas? Es racional y eficiente. –

+5

Luego tendrá dos referencias al mismo objeto. Una referencia piensa que es una 'Lista ' y la otra piensa que es una 'Lista '. Si agrega objetos usando la nueva referencia que no son cadenas, la referencia anterior no podrá acceder a ellos sin lanzar una 'ClassCastException'. –

1
List<Object> ofObjects = new ArrayList<Object>(ofStrings); 

como en:

import java.util.*; 
class C { 
    public static void main(String[] args) { 
    List<String> s = new ArrayList<String>(); 
    s.add("S"); 
    List<Object> o = new ArrayList<Object>(s); 
    o.add(new Object()); 
    System.out.println( o); 

    } 
} 

Como alternativa, se puede intentar el método addAll, si la lista de objetos es una lista existente.

5

Personalmente, si bien las dos respuestas actualmente mejor evaluadas son correctas, no creo que ninguna de ellas resuelva el problema de una manera elegante y reutilizable, especialmente si tiene que hacer esto muy a menudo.

Suponga que tiene un viejo código heredado/dependencia que no se puede cambiar en cualquier forma (por lo que sería al menos aceptar List<? extends Object> como @ReverendGonzo sugirió in his comment. Supongamos también, que necesita hablar con este módulo legado mucho.

No creo que el fundido/copiado todo el tiempo sea soportable a largo plazo. Hace que su código sea vulnerable a errores insidiosos y difíciles de seguir o ligeramente (o drásticamente) ineficiente y difícil de leer.

Para tener un código de producción eficiente y legible, es mejor encapsular la parte sucia en un módulo separado que se ocupa de lo contrario yeso inofensivo pero feo.

class ProductionCode { 
    public void doJob() { 
     List<String> strings = Arrays.asList("pear", "apple", "peach"); 
     StringMagicUtils.dealWithStrings(strings); 
    } 
} 

class StringMagicUtils { 
    @SuppressWarnings("unchecked") 
    public static void dealWithStrings(List<String> strings) { 
     ExternalStringMagic.dealWithStringsAsObjects((List) strings); 
    } 
} 

// Legacy - cannot edit this wonderful code below ˇˇ 
class ExternalStringMagic { 
    public static void dealWithStringsAsObjects(List<Object> stringsAsObjects) { 
     // deal with them as they please 
    } 
} 
Cuestiones relacionadas