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?

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 )


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

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.


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

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

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

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)

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

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.