Вопрос:

Преобразование списка <Integer> в список <String>

java string collections integer

175728 просмотра

20 ответа

1393 Репутация автора

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

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

Автор: ChrisThomas123 Источник Размещён: 20.08.2008 06:29

Ответы (20)


72 плюса

21606 Репутация автора

Решение

Насколько я знаю, итерации и создание экземпляров - единственный способ сделать это. Что-то вроде (для потенциальной помощи других, так как я уверен, что вы знаете, как это сделать):

List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<String>(oldList.size()) 
for (Integer myInt : oldList) { 
  newList.add(String.valueOf(myInt)); 
}
Автор: jsight Размещён: 20.08.2008 06:34

2 плюса

21606 Репутация автора

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

Автор: jsight Размещён: 20.08.2008 06:42

9 плюса

64014 Репутация автора

Вместо использования String.valueOf я бы использовал .toString (); он избегает некоторых из автоматического бокса, описанного @ johnathan.holland

Javadoc говорит, что valueOf возвращает то же самое, что и Integer.toString ().

List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());

for (Integer myInt : oldList) { 
  newList.add(myInt.toString()); 
}
Автор: ScArcher2 Размещён: 20.08.2008 06:45

2 плюса

8282 Репутация автора

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

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

Автор: Outlaw Programmer Размещён: 20.08.2008 06:53

9 плюса

3423 Репутация автора

Источник для String.valueOf показывает это:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Не то чтобы это имело большое значение, но я бы использовал toString.

Автор: Mike Polen Размещён: 20.08.2008 07:03

1 плюс

15199 Репутация автора

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

Автор: DrPizza Размещён: 20.08.2008 08:25

3 плюса

22272 Репутация автора

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

CollectionUtils

Что-то, чтобы рассмотреть, если вы уже используете общие коллекции в вашем проекте.

Автор: serg10 Размещён: 20.08.2008 08:26

40 плюса

26901 Репутация автора

То, что вы делаете, хорошо, но если вы чувствуете необходимость «Java-it-up», вы можете использовать Transformer и метод сбора от Apache Commons , например:

public class IntegerToStringTransformer implements Transformer<Integer, String> {
   public String transform(final Integer i) {
      return (i == null ? null : i.toString());
   }
}

..а потом..

CollectionUtils.collect(
   collectionOfIntegers, 
   new IntegerToStringTransformer(), 
   newCollectionOfStrings);
Автор: SCdF Размещён: 21.08.2008 01:24

3 плюса

226414 Репутация автора

Людям, обеспокоенным «боксом» в ответе jsight: их нет. String.valueOf(Object)используется здесь, и никакой распаковки в intникогда не выполняется.

Используете ли вы Integer.toString()или String.valueOf(Object)зависит от того, как вы хотите обрабатывать возможные нули. Вы хотите сгенерировать исключение (возможно) или иметь «нулевые» строки в своем списке (возможно). Если первое, вы хотите бросить NullPointerExceptionили какой-то другой тип?

Кроме того, один маленький недостаток в ответе jsight: Listэто интерфейс, вы не можете использовать новый оператор на нем. Я бы, вероятно, использовал java.util.ArrayListв этом случае, тем более, что мы заранее знаем, как долго будет длиться список.

Автор: erickson Размещён: 28.08.2008 06:35

2 плюса

128987 Репутация автора

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

    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);
Автор: Tom Hawtin - tackline Размещён: 11.09.2008 08:40

0 плюса

128987 Репутация автора

Просто для удовольствия, решение, использующее инфраструктуру 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))
Автор: Tom Hawtin - tackline Размещён: 14.09.2008 09:25

0 плюса

0 Репутация автора

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

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

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

Автор: John Wright Размещён: 24.09.2008 07:27

90 плюса

22459 Репутация автора

Используя Google Collections из Guava-Project , вы можете использовать transformметод в классе Lists

import com.google.common.collect.Lists;
import com.google.common.base.Functions

List<Integer> integers = Arrays.asList(1, 2, 3, 4);

List<String> strings = Lists.transform(integers, Functions.toStringFunction());

ListВозвращаемый transformэто вид в списке основы - преобразование будет применяться при каждом доступе к преобразованному списку.

Имейте в виду , что Functions.toStringFunction()будет бросать NullPointerExceptionпри нанесении на нуль, поэтому используйте его только если вы уверены , что ваш список не будет содержать нуль.

Автор: Ben Lings Размещён: 04.08.2009 12:04

2 плюса

10520 Репутация автора

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

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 применяет функцию преобразования только во время итерации по результату.

Автор: Mario Fusco Размещён: 07.03.2010 12:40

8 плюса

24127 Репутация автора

Вот однострочное решение без читерства с не-JDK библиотекой.

List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));
Автор: Garrett Hall Размещён: 25.04.2011 06:42

-1 плюса

761 Репутация автора

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

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

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

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

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

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

Удачи!

Автор: Rodney P. Barbati Размещён: 07.09.2012 05:40

68 плюса

5963 Репутация автора

Решение для Java 8. Немного длиннее, чем Guava, но, по крайней мере, вам не нужно устанавливать библиотеку.

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

//...

List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = integers.stream().map(Object::toString)
                                        .collect(Collectors.toList());
Автор: Trejkaz Размещён: 11.04.2014 11:52

5 плюса

1013 Репутация автора

Другое решение с использованием Guava и Java 8

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
Автор: sandrozbinden Размещён: 25.04.2014 12:38

0 плюса

1829 Репутация автора

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

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();
    }
Автор: nagendra547 Размещён: 29.08.2017 04:27

0 плюса

231 Репутация автора

List<String> stringList = integerList.stream().map((Object s)->String.valueOf(s)).collect(Collectors.toList())
Автор: Mahesh Yadav Размещён: 19.06.2019 11:11
Вопросы из категории :
32x32