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

java string collections integer

175728 просмотра

20 ответа

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

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

Автор: ChrisThomas123 Источник Размещён: 19.06.2019 02:12

Ответы (20)


72 плюса

Решение

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

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

90 плюса

Используя 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

68 плюса

Решение для 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

40 плюса

То, что вы делаете, хорошо, но если вы чувствуете необходимость «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

9 плюса

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

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

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

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

9 плюса

Вместо использования 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

8 плюса

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

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

5 плюса

Другое решение с использованием 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

3 плюса

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

CollectionUtils

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

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

3 плюса

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

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

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

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

2 плюса

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

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

2 плюса

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

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

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

2 плюса

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

    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

2 плюса

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

1 плюс

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

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

0 плюса

Просто для удовольствия, решение, использующее инфраструктуру 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 плюса

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

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

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

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

0 плюса

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

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 плюса

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

-1 плюса

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

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

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

При этом для преобразования без преобразования измените исходный список 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
32x32