How can I convert ArrayList<Object> to ArrayList<String>?

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

I tried:

ArrayList<String> list2 = (String)list;

But it gave me a compile error.

226220 次浏览

Since this is actually not a list of strings, the easiest way is to loop over it and convert each item into a new list of strings yourself:

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

Or when you're not on Java 16 yet:

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

Or when you're not on Java 8 yet:

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

Or when you're not on Java 7 yet:

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

Note that you should be declaring against the interface (java.util.List in this case), not the implementation.

It's not safe to do that!
Imagine if you had:

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

It wouldn't make sense to convert the list of those Objects to any type.

Your code ArrayList<String> list2 = (String)list; does not compile because list2 is not of type String. But that is not the only problem.

Using guava:

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

Here is another alternative using Guava

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

If you want to do it the dirty way, try this.

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

Advantage: here you save time by not iterating over all objects.

Disadvantage: may produce a hole in your foot.

Using Java 8 you can do:

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

Using 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)));

With Java Generics Takes a list of X and returns a list of T that extends or implements X, Sweet!

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

You can use wildcard to do this as following

ArrayList<String> strList = (ArrayList<String>)(ArrayList<?>)(list);

A simple solution:

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

Note: this works when the list contains all the elements of datatype String.