¿Cómo puedo convertir ArrayList <Object> en ArrayList <String>?

94
ArrayList<Object> list = new ArrayList<Object>();
list.add(1);
list.add("Java");
list.add(3.14);
System.out.println(list.toString());

Lo intenté:

ArrayList<String> list2 = (String)list; 

Pero me dio un error de compilación.

rtf
fuente
5
¿Por qué quieres hacer eso? Quiero decir que no es seguro. Eche un vistazo al ejemplo.
athspk
6
Estás poniendo no cadenas en la lista. ¿Cuál es su expectativa de lo que sucede si las obliga a ser cuerdas?
Ben Zotto
5
Supongo que quiso decir: ArrayList <String> list2 = (ArrayList <String>) list;
Costi Ciudatu

Respuestas:

130

Dado que en realidad no es una lista de cadenas, la forma más sencilla es recorrerla y convertir cada elemento en una nueva lista de cadenas usted mismo:

List<String> strings = list.stream()
   .map(object -> Objects.toString(object, null))
   .collect(Collectors.toList());

O cuando aún no estás en Java 8:

List<String> strings = new ArrayList<>(list.size());
for (Object object : list) {
    strings.add(Objects.toString(object, null));
}

O cuando aún no estás en Java 7:

List<String> strings = new ArrayList<String>(list.size());
for (Object object : list) {
    strings.add(object != null ? object.toString() : null);
}

Tenga en cuenta que debe declarar contra la interfaz ( java.util.Listen este caso), no la implementación.

BalusC
fuente
6
Me gusta cómo se conservan los valores nulos en esta implementación.
4
Si lo usa String.valueOf(object), no tendrá que hacer object != null ? object.toString() : nullnada
user219882
2
@Tomas: agregaría una cadena con valor en "null"lugar del literal null. Depende además de las recompensas comerciales si eso es deseable o no. Para mí, no habría sido aceptable en absoluto, ya que introduce un error potencialmente importante.
BalusC
1
@Tomas: "null"no lo es nullen absoluto. El nulltiene un significado especial en Java. No tiene sentido verse obligado a hacerlo if (item.equals("null"))cuando se verifica eso después.
BalusC
1
@Tomas: de esta manera solo estás derrotando la fuerte naturaleza de escritura de Java. Pero como se dijo, depende de los requisitos comerciales si eso es deseable. Para mí, eso es simplemente inaceptable. Haz lo que quieras y el tiempo te enseñará :)
BalusC
18

¡No es seguro hacer eso!
Imagínese si tuviera:

ArrayList<Object> list = new ArrayList<Object>();
list.add(new Employee("Jonh"));
list.add(new Car("BMW","M3"));
list.add(new Chocolate("Twix"));

No tendría sentido convertir la lista de esos Objetos a ningún tipo.

athspk
fuente
1
A menos que tengan un Object#toString()método anulado. Sin embargo, la conversión completa de tipos de X a String para otros fines que no sean la presentación humana no tiene mucho sentido.
BalusC
13

Si quieres hacerlo de la manera sucia, prueba esto.

@SuppressWarnings("unchecked")
public ArrayList<String> convert(ArrayList<Object> a) {
   return (ArrayList) a;
}

Ventaja: aquí se ahorra tiempo al no iterar sobre todos los objetos.

Desventaja: puede producir un agujero en su pie.

Per Lindberg
fuente
12

Usando guayaba :

List<String> stringList=Lists.transform(list,new Function<Object,String>(){
    @Override
    public String apply(Object arg0) {
        if(arg0!=null)
            return arg0.toString();
        else
            return "null";
    }
});
Emil
fuente
11

Usando Java 8 puedes hacer:

List<Object> list = ...;
List<String> strList = list.stream()
                           .map( Object::toString )
                           .collect( Collectors.toList() );
Scadge
fuente
10

Puede usar comodines para hacer esto de la siguiente manera

ArrayList<String> strList = (ArrayList<String>)(ArrayList<?>)(list);
Hellrocker
fuente
8

Aquí hay otra alternativa usando Guayaba

List<Object> lst ...    
List<String> ls = Lists.transform(lst, Functions.toStringFunction());
husayt
fuente
5

Su código ArrayList<String> list2 = (String)list;no se compila porque list2no es de tipo String. Pero ese no es el único problema.

fastcodejava
fuente
0

Usando Java 8 lambda:

ArrayList<Object> obj = new ArrayList<>();
obj.add(1);
obj.add("Java");
obj.add(3.14);

ArrayList<String> list = new ArrayList<>();
obj.forEach((xx) -> list.add(String.valueOf(xx)));
Ankush soni
fuente
0

Con Java Generics Toma una lista de X y devuelve una lista de T que extiende o implementa X, ¡Dulce!

    // the cast is is actually checked via the method API
@SuppressWarnings("unchecked")
public static <T extends X, X> ArrayList<T> convertToClazz(ArrayList<X> from, Class<X> inClazz, Class<T> outClazz) {
    ArrayList<T> to = new ArrayList<T>();
    for (X data : from) {
        to.add((T) data);
    }
    return to;
}
Solo yo
fuente
0

Una solución sencilla:

List<Object> lst  =listOfTypeObject;   
ArrayList<String> aryLst = new ArrayList<String>();
    for (int i = 0; i < lst.size(); i++) {
        aryLst.add(lst.get(i).toString());
    }

Nota: esto funciona cuando la lista contiene todos los elementos del tipo de datos String.

S Krishna
fuente