Expresión lambda para convertir array / List of String a array / List of Integers

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 logro lo mismo con un lambda, dado un conjunto de cadenas para convertir a una matriz de enteros.

Podría crear métodos auxiliares que convertirían una lista (matriz) de tipo T en una lista (matriz) de tipo U utilizando la operación de map la map .

 //for lists public static  List convertList(List from, Function func) { return from.stream().map(func).collect(Collectors.toList()); } //for arrays public static  U[] convertArray(T[] from, Function func, IntFunction generator) { return Arrays.stream(from).map(func).toArray(generator); } 

Y úsalo así:

 //for lists List stringList = Arrays.asList("1","2","3"); List 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 (ver referencias del Método )

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

Los métodos auxiliares de la respuesta aceptada no son necesarios. Los flujos se pueden usar con lambdas o, por lo general, se acortan utilizando las referencias a los métodos . Los flujos permiten operaciones funcionales. map() convierte los elementos y collect(...) o toArray() envuelve la secuencia en una matriz o colección.

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

1 Convertir List a List

 List l1 = Arrays.asList("1", "2", "3"); List r1 = l1.stream().map(Integer::parseInt).collect(Collectors.toList()); // the longer full lambda version: List r1 = l1.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList()); 

2 Convertir List a int[]

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

3 Convertir String[] en List

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

4 Convertir String[] a int[]

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

5 Convertir String[] a List

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

6 (bonus) Convertir int[] en String[]

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

Muchas más variaciones son posibles, por supuesto.

También vea la versión de Ideone de estos ejemplos . Puede hacer clic en la horquilla y luego ejecutar para ejecutar en el navegador.

EDITAR: Como se señaló en los comentarios, esta es una versión mucho más simple: 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 todavía es bastante lenta (toma alrededor de 100 veces más que una para el ciclo – 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 en ints (no tienes que hacer esto si solo quieres enteros)
  5. .toArray () convierte la secuencia de nuevo en una matriz

También puedes usar,

 List list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); Integer[] array = list.stream() .map( v -> Integer.valueOf(v)) .toArray(Integer[]::new); 

Para la lista:

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

Para Array:

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

Además, controle cuando la matriz de cadenas no tenga elementos:

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