Expresión Lambda para convertir matriz / Lista de cadenas en matriz / Lista de enteros

111

Dado que Java 8 viene con poderosas expresiones lambda,

Me gustaría escribir una función para convertir una lista / matriz de cadenas en una matriz / lista de enteros, flotantes, dobles, etc.

En Java normal, sería tan simple como

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

Pero, ¿cómo puedo lograr lo mismo con una lambda, dada una matriz de cadenas para convertir en una matriz de enteros?

Reddy
fuente

Respuestas:

128

Puede crear métodos auxiliares que conviertan una lista (matriz) de tipo Ten una lista (matriz) de tipo Uutilizando la mapoperación on 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);
}

Y utilícelo así:

//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);


Tenga en cuenta que s -> Integer.parseInt(s)podría reemplazarse con Integer::parseInt(consulte las referencias de métodos )

Alexis C.
fuente
5
Si está usando Guayaba, también puede usar Lists.transform().
Alexandros
Muy buen ejemplo. La función hace que el código sea más versátil y potente. Gracias !!!
Marcelo Rebouças
127
List<Integer> intList = strList.stream()
                               .map(Integer::valueOf)
                               .collect(Collectors.toList());
ZehnVon12
fuente
5
¿Puedes explicar esto un poco?
Unheilig
1
Esto es convertir una lista de String en una secuencia y luego mapear / convertir cada elemento de la lista en Integer y luego recopilarlo en una lista.
hemanto
5
Esta debería ser la respuesta aceptada, ya que el objetivo de lambdas (la pregunta original pide una expresión lambda) es evitar definir una nueva función. Además de lo cual, esta respuesta usa elegantemente la función Integer :: valueOf existente
Jonathan Benn
31

Los métodos auxiliares de la respuesta aceptada no son necesarios. Los flujos se pueden utilizar con lambdas o, por lo general, se pueden acortar mediante referencias de método . Los flujos permiten operaciones funcionales. map()convierte los elementos y collect(...)o toArray()envolver la parte posterior de flujo de carga en una matriz o colección.

La charla de Venkat Subramaniam (video) lo explica mejor que yo.

1 Convertir List<String>aList<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 Convertir List<String>aint[]

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

3 Convertir String[]aList<Integer>

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

4 Convertir String[]aint[]

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

5 Convertir String[] aList<Double>

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

6 (bonificación) Convertir int[] aString[]

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

Por supuesto, son posibles muchas más variaciones.

Consulte también la versión de Ideone de estos ejemplos . Puede hacer clic en la bifurcación y luego ejecutar para ejecutar en el navegador.

Stan Kurdziel
fuente
7

EDITAR: Como se señaló en los comentarios, esta es una versión mucho más simple: de Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() esta manera podemos omitir toda la conversión hacia y desde una lista.


Encontré otra solución de una línea, pero sigue siendo bastante lenta (toma alrededor de 100 veces más que un ciclo for; probado en una matriz de 6000 0)

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

Que hace esto:

  1. Arrays.asList () convierte la matriz en una lista
  2. .stream lo convierte en un Stream (necesario para realizar un mapa)
  3. .map (Integer :: parseInt) convierte todos los elementos de la secuencia en enteros
  4. .mapToInt (i-> i) convierte todos los enteros a enteros (no tienes que hacer esto si solo quieres enteros)
  5. .toArray () convierte el Stream de nuevo en una matriz
Colador
fuente
13
No necesita los pasos 1 y 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk
3

Para la lista:

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

Para matriz:

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

También puedes usar,

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);
usuario2182920
fuente
0

No lo encontré en las respuestas anteriores, entonces, con Java 8 y streams:

Convertir String[]a Integer[]:

Arrays.stream(stringArray).map(Integer::valueOf).toArray(Integer[]::new)
LeoLozes
fuente
-1

Además, controla cuando la matriz de cadenas no tiene elementos:

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

Usé maptoInt () con la operación Lambda para convertir la cadena a Integer

int[] arr = Arrays.stream(stringArray).mapToInt(item -> Integer.parseInt(item)).toArray();
Lotia profunda
fuente
-3

Arrays.toString (int []) funciona para mí.

Praveen Codur
fuente
No respondo a la pregunta: "Cómo lograr esto con lambdas".
Sergei Sirik