Как преобразовать ArrayList <Object> в ArrayList <String>?

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

Но это дало мне ошибку компиляции.

rtf
источник
5
Почему ты хочешь это сделать? Я имею в виду, что это небезопасно. Взгляните на пример.
athspk
6
Вы помещаете в список не строки. Что вы ожидаете от того, что произойдет, если вы заставите их быть струнами?
Бен Зотто
5
Я полагаю, вы имели в виду: список ArrayList <String> list2 = (ArrayList <String>) list;
Costi Ciudatu 03

Ответы:

132

Поскольку на самом деле это не список строк, проще всего перебрать его и самостоятельно преобразовать каждый элемент в новый список строк:

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в данном случае), а не реализации.

BalusC
источник
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"));

Было бы бессмысленно преобразовывать список этих объектов в какой-либо тип.

Athspk
источник
1
Если у них нет Object#toString()переопределенного метода. Однако полное преобразование типа из X в String для других целей, кроме человеческого представления, действительно не имеет большого смысла.
BalusC 03
13

Если вы хотите сделать это грязным способом, попробуйте это.

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

Преимущество: здесь вы экономите время, не перебирая все объекты.

Недостаток: на стопе может образоваться отверстие.

Пер Линдберг
источник
13

Используя Java 8, вы можете:

List<Object> list = ...;
List<String> strList = list.stream()
                           .map( Object::toString )
                           .collect( Collectors.toList() );
Scadge
источник
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";
    }
});
Эмиль
источник
12

Вы можете использовать подстановочный знак, чтобы сделать это следующим образом

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. Но это не единственная проблема.

fastcodejava
источник
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, 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;
}
Просто я
источник
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());
    }

Примечание: это работает, когда список содержит все элементы типа данных String.

С Кришна
источник