Подтвердить что ты не робот

Lambda выражение для преобразования массива/Список строк в массив/Список целых чисел

Так как Java 8 содержит мощные лямбда-выражения,

Я хотел бы написать функцию для преобразования List/array строк в массив/Список целых чисел, Floats, Doubles и т.д.

В обычной Java это будет так же просто, как

for(String str : strList){
   intList.add(Integer.valueOf(str));
}

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

4b9b3361

Ответ 1

Вы можете создать вспомогательные методы, которые преобразуют список (массив) типа T в список (массив) типа U с помощью map на stream.

//for lists
public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) {
    return from.stream().map(func).collect(Collectors.toList());
}

//for arrays
public static <T, U> U[] convertArray(T[] from, 
                                      Function<T, U> func, 
                                      IntFunction<U[]> generator) {
    return Arrays.stream(from).map(func).toArray(generator);
}

И используйте его следующим образом:

//for lists
List<String> stringList = Arrays.asList("1","2","3");
List<Integer> integerList = convertList(stringList, s -> Integer.parseInt(s));

//for arrays
String[] stringArr = {"1","2","3"};
Double[] doubleArr = convertArray(stringArr, Double::parseDouble, Double[]::new);

<ч/" > Обратите внимание, что s -> Integer.parseInt(s) можно заменить на Integer::parseInt (см. Ссылки на методы)

Ответ 2

List<Integer> intList = strList.stream()
                               .map(Integer::valueOf)
                               .collect(Collectors.toList());

Ответ 3

Вспомогательные методы из принятого ответа не нужны. Streams может использоваться с lambdas или обычно сокращаться с использованием Ссылки на методы. Потоки позволяют выполнять функциональные операции. map() преобразует элементы и collect(...) или toArray() завершает поток обратно в массив или коллекцию.

Разговор Venkat Subramaniam (видео) объясняет это лучше меня.

1 Преобразуйте List<String> в List<Integer>

List<String> l1 = Arrays.asList("1", "2", "3");
List<Integer> r1 = l1.stream().map(Integer::parseInt).collect(Collectors.toList());

// the longer full lambda version:
List<Integer> r1 = l1.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());

2 Преобразуйте List<String> в int[]

int[] r2 = l1.stream().mapToInt(Integer::parseInt).toArray();

3 Преобразуйте String[] в List<Integer>

String[] a1 = {"4", "5", "6"};
List<Integer> r3 = Stream.of(a1).map(Integer::parseInt).collect(Collectors.toList());

4 Преобразуйте String[] в int[]

int[] r4 = Stream.of(a1).mapToInt(Integer::parseInt).toArray();

5 Преобразуйте String[] в List<Double>

List<Double> r5 = Stream.of(a1).map(Double::parseDouble).collect(Collectors.toList());

6 (бонус) Преобразовать int[] в String[]

int[] a2 = {7, 8, 9};
String[] r6 = Arrays.stream(a2).mapToObj(Integer::toString).toArray(String[]::new);

Конечно, возможны и другие варианты.

Также см. Идеальная версия этих примеров. Можно щелкнуть вилкой, а затем запустить ее в браузере.

Ответ 4

EDIT: Как отмечается в комментариях, это гораздо более простая версия: Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() Таким образом, мы можем пропустить все преобразование в список и из него.


Я нашел еще одно однострочное решение, но оно все еще довольно медленное (занимает примерно 100 раз дольше, чем для цикла - проверено на массиве 6000 0)

String[] stringArray = ...
int[] out= Arrays.asList(stringArray).stream().map(Integer::parseInt).mapToInt(i->i).toArray();

Что это делает:

  • Arrays.asList() преобразует массив в список
  • .stream преобразует его в поток (необходимый для выполнения карты)
  • .map(Integer:: parseInt) преобразует все элементы в потоке в целые числа
  • .mapToInt(i- > i) преобразует все целые числа в int (вам не нужно делать это, если вам нужны только целые числа)
  • .toArray() преобразует поток обратно в массив

Ответ 5

Вы также можете использовать

List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    Integer[] array = list.stream()
        .map( v -> Integer.valueOf(v))
        .toArray(Integer[]::new);

Ответ 6

Для списка:

List<Integer> intList 
 = stringList.stream().map(Integer::valueOf).collect(Collectors.toList());

Для массива:

int[] intArray = Arrays.stream(stringArray).mapToInt(Integer::valueOf).toArray();

Ответ 7

Я не нашел его в предыдущих ответах, поэтому с Java 8 и потоками:

Преобразовать String[] в Integer[]:

Arrays.stream(stringArray).map(Integer::valueOf).toArray(Integer[]::new)

Ответ 8

Кроме того - управление, когда строковый массив не имеет элементов:

Arrays.stream(from).filter(t -> (t != null)&&!("".equals(t))).map(func).toArray(generator) 

Ответ 9

Arrays.toString(int []) работает для меня.