Как преобразовать массив объектов в массив строк в Java


244

Я использую следующий код для преобразования массива объектов в массив строк:

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
Мне больше нравится ответ Wingwing: String [] stringArray = Arrays.copyOf (objectArray, objectArray.length, String []. Class); Это очень лаконично и работает. Я посчитал, сколько времени требуется и для его ответа, и для моего нынешнего подхода, они в значительной степени совпадают.
Фрэнк

Ответы:


381

Еще одна альтернатива System.arraycopy:

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

59
только на Java 1.6 и выше
newacct

10
Хмм. Я не мог заставить это работать, где длинный пример в оригинальном вопросе работает. Выдает java.lang.ArrayStoreException. Я получаю массив объектов из метода toArray для универсального ArrayList, содержащего мой пользовательский тип. Это не должно работать с генериками или что-то?
Ян Варли

4
@Ian, проблема в том, что objectArray содержит Objects, а не Strings (см. Комментарий mmyers к моему ответу, который страдает от той же проблемы).
Ишай

3
Я только что попробовал этот подход и, по крайней мере, в моем случае, я обнаружил, что производительность не так хороша, как сам сборка массива путем итерации. (Жаль, что мне нравилось это как однострочник!)
mdup

1
@mdup - довольно длинный лайнер. оберните это в методе возможно.
MasterJoe2

72

В Java 8:

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

Чтобы преобразовать массив других типов:

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

2
Это прекрасное произведение, удовлетворяющее требованию возможности эстетически преобразовывать массив нестроковых объектов в массив их эквивалентов toString. В настоящее время принятый ответ не делает этого.
b4n4n4p4nd4

Это работает, но если ваш список содержит пустые значения, вы получите исключение NullPointerException. Чтобы обойти эту проблему, смотрите: stackoverflow.com/questions/4581407/…
Тони Фалабелла

61

System.arraycopy, вероятно, является наиболее эффективным способом, но для эстетики я бы предпочел:

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

10
Это работает, только если все объекты являются строками; его текущий код работает, даже если это не так.
Майкл Майерс

Хорошая точка зрения. Я понимал, что toString - это просто способ приведения к String, а не намерение фактически заменить объекты чем-то другим. Если это то, что вам нужно сделать, то цикл является единственным способом.
Ишай

это не работает в Android 2.3.3 .. выдает ошибку, сообщающую, что метод copyof не определен. Я импортировал все нужные файлы (Ctrl + Shift + I) .. но все равно не работает.
user590849 26.10.12

3
@ user590849, мой ответ не использует copyof. Вы ссылаетесь на другой ответ?
Ишай

50

Я вижу, что были предоставлены некоторые решения, но не какие-либо причины, поэтому я объясню это подробно, так как считаю, что так же важно знать, что вы делали неправильно, просто чтобы получить «что-то», которое работает из данных ответов.

Сначала посмотрим, что скажет 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.

Это может выглядеть неважно, но, как вы увидите, это так ... Так что же не получается в следующей строке? Все объекты в списке являются String, но он не конвертирует их, почему?

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 создает экземпляры объектов, а не строк ...

Поэтому естественное решение, которое не упоминалось в этой теме, но это то, что 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

Каркас коллекций google предлагает хороший метод преобразования, чтобы вы могли преобразовать свои объекты в строки. Единственным недостатком является то, что он должен быть из 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 ()). Я не знаю, почему так вышло.
Ишай

5

Если вы хотите получить строковое представление объектов в вашем массиве, то да, другого способа сделать это нет.

Если вы знаете, что ваш массив Object содержит только строки, вы также можете сделать это (instread для вызова toString ()):

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

Единственный случай, когда вы могли бы использовать приведение к String [] объекта Object_Array, было бы, если бы массив, на который он ссылается, фактически был бы определен как String [], например, это будет работать:

    Object[] o = new String[10];
    String[] s = (String[]) o;

5

Это хорошо, но не работает, как заметил mmyers, из-за квадратных скобок:

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

Этот уродлив, но работает:

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

Если вы используете этот код, вы должны быть уверены, что строки, возвращаемые toString () ваших объектов, не содержат запятых.


1
Интересное предложение, но сначала вы должны удалить [и] на первом и последнем элементах.
Майкл Майерс

1
великолепна, пока не выполнит свою работу :)
AZ_ 27.10.10

2
Это не работает, если любая строка содержит запятую (,)
Андреас Бергер

2

Для вашей идеи, на самом деле вы приближаетесь к успеху, но если вам это нравится, то все будет в порядке:

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

Кстати, использование вспомогательного метода Arrays довольно хорошо и делает код элегантным.



1

Вы можете использовать тип-конвертер . Для преобразования массива любых типов в массив строк вы можете зарегистрировать свой собственный конвертер:

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

0

Легко изменить без головной боли. Конвертировать любой массив объектов в строковый массив. Объект drivex [] = {1,2};

    for(int i=0; i<drive.length ; i++)
        {
            Str[i]= drivex[i].toString();
            System.out.println(Str[i]); 
        }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.