Як я можу перетворити ArrayList <Object> на ArrayList <String>?


94
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
Ви вносите в список не рядки. Як ви очікуєте того, що станеться, якщо ви змусите їх бути рядками?
Бен Зотто

5
Припускаю, ви мали на увазі: ArrayList <String> list2 = (ArrayList <String>) list;
Costi Ciudatu

Відповіді:


130

Оскільки це насправді не список рядків, найпростіший спосіб - перевести цикл на нього та самостійно перетворити кожен елемент у новий список рядків:

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
Мені подобається, як збереглися нульові значення цієї реалізації.

4
Якщо ви використовуєте String.valueOf(object), ви не повинні робити object != null ? object.toString() : nullречі
user219882

2
@Tomas: він додав би рядок зі значенням "null"замість буквального null. Далі це залежить від вимог бізнесу, бажано це чи ні. Для мене це взагалі не було б прийнятним, оскільки воно вводить потенційно велику помилку.
BalusC

1
@Tomas: "null"зовсім не є null. У nullJava є особливе значення. Немає сенсу примушувати це робити, if (item.equals("null"))перевіряючи на це згодом.
BalusC

1
@Tomas: таким чином ви перемагаєте лише сильний набір тексту Java. Але, як було сказано, це залежить від вимог бізнесу, чи бажано це. Для мене це просто неприпустимо. Робіть все, що завгодно, і час навчить :)
BalusC

18

Це не безпечно робити!
Уявіть, якби у вас було:

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 у String для інших цілей, ніж людське представлення, насправді не має особливого сенсу.
BalusC

13

Якщо ви хочете зробити це брудним способом, спробуйте це.

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

Перевага: тут ви економите час, не перебираючи на всі об’єкти.

Недолік: може утворити діру на нозі.


12

Використання гуави :

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

11

За допомогою Java 8 ви можете:

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

10

Ви можете використовувати підстановочний знак, щоб зробити це наступним чином

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

8

Ось ще одна альтернатива використання Guava

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

5

Ваш код ArrayList<String> list2 = (String)list;не компілюється, оскільки list2він не має типу String. Але це не єдина проблема.


0

Використання Java 8 лямбда:

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 Generics бере список X і повертає список 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;
}

0

Просте рішення:

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

Примітка. Це працює, коли список містить усі елементи типу рядка даних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.