如何在Java中将对象数组转换为字符串数组

279

我使用以下代码将一个对象数组转换为字符串数组:

Object Object_Array[]=new Object[100];
// ... get values in the Object_Array

String String_Array[]=new String[Object_Array.length];

for (int i=0;i<String_Array.length;i++) String_Array[i]=Object_Array[i].toString();

但我想知道是否有其他方法来做到这一点,例如:

String_Array=(String[])Object_Array;

但这会导致运行时错误:Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

应该如何正确处理?


3
我最喜欢Waxwing的回答:String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);非常简洁且有效。我对他的回答和我的当前方法计时,它们所花费的时间几乎相同。 - Frank
11个回答

410

除了使用 System.arraycopy 之外,还有另一个选择:

String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);

61
仅适用于Java 1.6及以上版本。 - newacct
11
嗯,我无法让这个工作,而原始问题中的长格式示例确实可以工作。它抛出java.lang.ArrayStoreException异常。我从一个包含我的自定义类型的通用ArrayList上的toArray方法获取对象数组。这不应该与泛型一起使用吗? - Ian Varley
4
@Ian,问题在于objectArray包含的是对象而不是字符串(请参阅mmyers对我回答的评论,该评论也存在相同的问题)。 - Yishai
3
我刚刚尝试了这种方法,但至少在我的情况下,发现性能不如通过迭代自己构建数组。 (很遗憾,我喜欢它作为一行代码!) - mdup
1
@mdup - 这是一行非常长的代码。或许可以将其封装成一个方法。 - MasterJoe

107

在Java 8中:

String[] strings = Arrays.stream(objects).toArray(String[]::new);

将其他类型的数组转换为:

String[] strings = Arrays.stream(obj).map(Object::toString).
                   toArray(String[]::new);

3
这是一项美妙的工作,并满足将非字符串对象数组美学地转换为它们的toString等效数组的要求。目前被接受的答案无法实现这一点。 - b4n4n4p4nd4
2
这个代码可以工作,但是如果你的列表包含空值,就会出现NullPointerException异常。为了避免这个问题,请参见以下链接:https://dev59.com/6G455IYBdhLWcg3wCPbh - Tony Falabella
当我使用Arrays.stream时,我在Android Studio IDE中遇到了一个错误。"无法解析方法'stream()'。我知道我正在使用正确的Java版本。 - GhostRavenstorm

67

System.arraycopy可能是最有效的方法,但出于美观考虑,我更喜欢:

 Arrays.asList(Object_Array).toArray(new String[Object_Array.length]);

10
只有当所有的对象都是字符串时才能这样做;他目前的代码即使对象不是字符串也可以工作。 - Michael Myers
好的观点。我将toString理解为将对象强制转换为字符串的方法,而不是实际替换对象的意图。如果您需要这样做,那么循环是唯一的方法。 - Yishai
这个在Android 2.3.3中不起作用。它给了我一个错误,说copyof方法没有定义。我导入了所有正确的文件(ctrl+shift+I)..但它还是不起作用。 - user590849
3
@user590849,我的回答没有使用copyof。您是指另一个回答吗? - Yishai

51

我看到有一些解决方案被提供了,但没有任何原因,所以我将详细解释一下,因为我认为知道你做错了什么比从给定的答复中获得"某些"能够工作更重要。

首先,让我们看看Oracle有什么要说的

 * <p>The returned array will be "safe" in that no references to it are
 * maintained by this list.  (In other words, this method must
 * allocate a new array even if this list is backed by an array).
 * The caller is thus free to modify the returned array.

虽然看起来可能不重要,但正如您将看到的那样它确实很重要... 那么以下代码为什么会失败呢?列表中的所有对象都是字符串,但它没有将它们转换,为什么?

List<String> tList = new ArrayList<String>();
tList.add("4");
tList.add("5");
String tArray[] = (String[]) tList.toArray();   

也许你们中的许多人认为这段代码是做同样的事情,但实际上并不是。

Object tSObjectArray[] = new String[2];
String tStringArray[] = (String[]) tSObjectArray;

实际上,代码执行的内容是这样的。Javadoc已经说明了!它将实例化一个新数组,而这个数组将是对象数组!!!

Object tSObjectArray[] = new Object[2];
String tStringArray[] = (String[]) tSObjectArray;   

tList.toArray实例化的是Objects而不是Strings...

因此,自然的解决方案并未在该线程中提到,但这正是Oracle推荐的做法:

String tArray[] = tList.toArray(new String[0]);

希望这已经足够清楚了。


性能方面稍作更正:String tArray[] = tList.toArray(new String[tList.size()]);否则数组必须再次调整大小... - Lonzak
1
好的解释。只有一件事,如果内存消耗或性能是一个问题,不要复制数组。要么在需要时将元素转换为字符串 (String)Object_Array[i]Object_Array[i].toString(),要么将数组分配为字符串数组 Object Object_Array[]=new String[100]; ... 获取值 ... 然后转换 String_Array=(String[])Object_Array,这样就可以工作了。 - Solostaran14
1
这会抛出 ArrayStoreException 异常。 - iltaf khalid

7

谷歌集合框架提供了一个非常好的转换方法,可以将对象转换为字符串。唯一的缺点是它必须从Iterable到Iterable进行转换,但这是我会采取的方式:

Iterable<Object> objects = ....... //Your chosen iterable here
Iterable<String> strings = com.google.common.collect.Iterables.transform(objects, new Function<Object, String>(){
        String apply(Object from){
             return from.toString();
        }
 });

这种方式不涉及使用数组,但我认为这是我更喜欢的方法。


1
@Yishai:不,数组没有实现Iterable。在它们上面的迭代是在JLS中特别定义的。 - newacct
@newacct,非常正确,我的意思是数组可以很容易地包装在Iterable中(Arrays.asList())。我不知道为什么会这样。 - Yishai

7

这个方法很好,但是像mmyers指出的那样,由于方括号的原因无法工作:

Arrays.toString(objectArray).split(",")

这个方法很丑陋,但是可行:

Arrays.toString(objectArray).replaceFirst("^\\[", "").replaceFirst("\\]$", "").split(",")

如果您使用此代码,则必须确保对象的toString()返回的字符串不包含逗号。


1
有趣的建议,但你首先必须删除第一个和最后一个元素上的 [ 和 ]。 - Michael Myers
1
美轮美奂,直到完成任务 :) - AZ_
2
如果任何字符串包含逗号(,),则此方法无法正常工作。 - Andreas Berger

5
如果你想获取数组中对象的字符串表示形式,那么是的,没有其他方法可以做到。如果你知道你的Object数组只包含字符串,你也可以这样做(而不是调用toString()):
for (int i=0;i<String_Array.length;i++) String_Array[i]= (String) Object_Array[i];

只有在Object_Array引用的数组实际上被定义为String[]时,您才能使用Object_Array的String[]转换。例如,以下情况可以工作:
    Object[] o = new String[10];
    String[] s = (String[]) o;

4
您可以使用 type-converter。为了将任意类型的数组转换为字符串数组,您可以注册自己的转换器:
 TypeConverter.registerConverter(Object[].class, String[].class, new Converter<Object[], String[]>() {

        @Override
        public String[] convert(Object[] source) {
            String[] strings = new String[source.length];
            for(int i = 0; i < source.length ; i++) {
                strings[i] = source[i].toString();
            }
            return strings;
        }
    });

并使用它

   Object[] objects = new Object[] {1, 23.43, true, "text", 'c'};
   String[] strings = TypeConverter.convert(objects, String[].class);

3

根据您的想法,实际上您正在接近成功,但如果您这样做应该会更好:

for (int i=0;i<String_Array.length;i++) String_Array[i]=(String)Object_Array[i];

顺便说一下,使用Arrays实用方法相当不错,可以使代码更加优雅。


2
Object arr3[]=list1.toArray();
   String common[]=new String[arr3.length];

   for (int i=0;i<arr3.length;i++) 
   {
   common[i]=(String)arr3[i];
  }

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