如何将 ArrayList<Object> 转换为 ArrayList<String>?

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

我尝试了:

ArrayList<String> list2 = (String)list; 

但是它给了我一个编译错误。


5
为什么你要这样做?我的意思是这样做不安全。看看这个例子。 - athspk
6
您正在将非字符串放入列表中。如果您强制将它们转换为字符串,您希望发生什么? - Ben Zotto
5
我理解你的意思是:ArrayList<String> list2 = (ArrayList<String>)list; (意为:定义一个 ArrayList<String> 类型的变量 list2,并将 list 转换为 ArrayList<String> 类型后赋值给 list2) - Costi Ciudatu
11个回答

176

因为这实际上不是一个字符串列表,最简单的方法是循环遍历它,并将每个项转换为一个新的字符串列表:

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

或者当你还没有使用 Java 16:

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

或者当你还没有使用Java 8时:

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

或者当你还没有使用Java 7时:

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

请注意,在此情况下应该声明对接口(java.util.List)而不是实现。


6
我喜欢这个实现方式保留了空值。 - user166390
4
如果你使用 String.valueOf(object),你就不必进行 object != null ? object.toString() : null 这样的操作。 - user219882
2
@Tomas:它将添加一个值为“null”的字符串,而不是字面上的null。这进一步取决于业务需求是否需要这样做。对我来说,这完全不可接受,因为它可能会引入一个重大的错误。 - BalusC
1
@Tomas:"null"根本不是null。在Java中,null有着特殊的含义。在之后检查时被迫执行if (item.equals("null"))毫无意义。 - BalusC
2
@Tomas:你这样做只是打败了Java的强类型特性。但是就像我所说的,这取决于业务需求是否需要这样做。对我来说,这是完全不可接受的。你想怎么做就怎么做吧,时间会告诉我们结果 :) - BalusC
显示剩余2条评论

16
您可以使用通配符来执行以下操作。
ArrayList<String> strList = (ArrayList<String>)(ArrayList<?>)(list);

16

这样做是不安全的!
想象一下,如果你有:

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

将那些对象列表转换成任何类型是没有意义的。


1
除非它们覆盖了 Object#toString() 方法。然而,将 X 类型转换为字符串以用于人类展示之外的其他目的确实没有太多意义。 - BalusC

15

使用Java 8可以实现:

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

14

如果你想采用简单粗暴的方法,可以尝试这个。

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

优点:不必遍历所有对象,节省时间。

缺点:可能会在你的脚上留下一个洞。


12

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

8

这里有另一种使用Guava的替代方案。

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

5

您的代码 ArrayList<String> list2 = (String)list; 无法编译,因为 list2 不是 String 类型。但这不是唯一的问题。


0

使用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)));

0

使用Java泛型,接受一个X类型的列表并返回一个T类型的列表,该T类型扩展或实现了X类型,太棒了!

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接