Преобразование списка <Integer>в список <String> - PullRequest
95 голосов
/ 20 августа 2008

У меня есть список целых чисел, List<Integer>, и я хотел бы преобразовать все целочисленные объекты в строки, таким образом заканчивая новым List<String>.

Естественно, я мог бы создать новый List<String> и пройти по списку, вызывая String.valueOf() для каждого целого числа, но мне было интересно, есть ли лучший (читай: более автоматический ) способ выполнения это?

Ответы [ 19 ]

2 голосов
/ 20 августа 2008

@ Джонатан: Я могу ошибаться, но я полагаю, что String.valueOf () в этом случае будет вызывать функцию String.valueOf (Object), а не попадать в String.valueOf (int). String.valueOf (Object) просто возвращает значение «null», если оно равно NULL, или вызывает Object.toString (), если оно не равно NULL, что не должно включать бокс (хотя, очевидно, речь идет о создании экземпляров новых строковых объектов).

2 голосов
/ 20 августа 2008

Я думаю, что использование Object.toString () для любых целей, кроме отладки, вероятно, является действительно плохой идеей, даже если в этом случае они функционально эквивалентны (при условии, что в списке нет нулей). Разработчики могут изменять поведение любого метода toString () без каких-либо предупреждений, включая методы toString () любых классов в стандартной библиотеке.

Даже не беспокойтесь о проблемах производительности, вызванных процессом упаковки / распаковки. Если производительность критична, просто используйте массив. Если это действительно важно, не используйте Java. Попытка перехитрить JVM приведет только к душевной боли.

2 голосов
/ 07 марта 2010

Lambdaj позволяет сделать это очень простым и понятным способом. Например, предположим, что у вас есть список целых чисел, и вы хотите преобразовать их в соответствующее строковое представление, вы могли бы написать что-то подобное;

List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
    public String convert(Integer i) { return Integer.toString(i); }
}

Lambdaj применяет функцию преобразования только во время итерации по результату.

2 голосов
/ 12 сентября 2008

Ответ только для экспертов:

    List<Integer> ints = ...;
    String all = new ArrayList<Integer>(ints).toString();
    String[] split = all.substring(1, all.length()-1).split(", ");
    List<String> strs = Arrays.asList(split);
1 голос
/ 21 августа 2008

Нельзя избежать «накладных расходов на бокс»; Стандартные контейнеры Java могут хранить только объекты, поэтому ваши целые должны быть упакованы в целые числа. В принципе, он мог бы избежать перехода от Object к Integer (поскольку это бессмысленно, поскольку Object достаточно хорош как для String.valueOf, так и для Object.toString), но я не знаю, достаточно ли умен для этого компилятор. Преобразование из String в Object должно быть более или менее запретным, поэтому я не буду беспокоиться об этом.

0 голосов
/ 29 августа 2017

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

It will be really good to remove the integer from the List<Integer> and free
the space, once it's added to List<String>.

Мы можем использовать итератор для достижения того же.

    List<Integer> oldList = new ArrayList<>();
    oldList.add(12);
    oldList.add(14);
    .......
    .......

    List<String> newList = new ArrayList<String>(oldList.size());
    Iterator<Integer> itr = oldList.iterator();
    while(itr.hasNext()){
        newList.add(itr.next().toString());
        itr.remove();
    }
0 голосов
/ 07 сентября 2012

Я просто хотел присоединиться к объектно-ориентированному решению проблемы.

Если вы моделируете доменные объекты, то решение находится в доменных объектах. Домен здесь представляет собой список целых чисел, для которых нам нужны строковые значения.

Самый простой способ - вообще не преобразовывать список.

При этом для преобразования без преобразования измените исходный список Integer на List of Value, где Value выглядит примерно так ...

class Value {
    Integer value;
    public Integer getInt()
    {
       return value;
    }
    public String getString()
    {
       return String.valueOf(value);
    }
}

Это будет быстрее и займет меньше памяти, чем копирование списка.

Удачи!

0 голосов
/ 15 сентября 2008

Просто для удовольствия, решение, использующее инфраструктуру fork-join jsr166y, которое должно быть в JDK7.

import java.util.concurrent.forkjoin.*;

private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
    ParallelArray.create(ints.size(), Integer.class, executor)
    .withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
        return String.valueOf(i);
    }})
    .all()
    .asList();

(Отказ от ответственности: не скомпилировано. Спецификация не завершена. И т. Д.)

Маловероятно, чтобы быть в JDK7 - это что-то вроде вывода типа и синтаксического сахара, чтобы сделать вызов withMapping менее подробным:

    .withMapping(#(Integer i) String.valueOf(i))
0 голосов
/ 24 сентября 2008

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

У нас есть класс статических методов, специально созданных для выполнения подобных задач. Поскольку код для этого очень прост, мы позволяем Hotspot выполнить оптимизацию за нас. Это, кажется, тема в моем коде в последнее время: написать очень простой (простой) код и позволить Hotspot сделать свое волшебство. У нас редко возникают проблемы с производительностью, связанные с таким кодом: когда появляется новая версия виртуальной машины, вы получаете все дополнительные преимущества в скорости и т. Д.

Как бы я ни любил коллекции Джакарты, они не поддерживают Generics и используют 1.4 в качестве ЖК-дисплея. Я опасаюсь коллекций Google, потому что они указаны как уровень поддержки Alpha!

...