Java 8 Stream y operación en arreglos

3 minutos de lectura

avatar de usuario
negrolabrador

Acabo de descubrir las nuevas capacidades de transmisión de Java 8. Viniendo de Python, me preguntaba si ahora había una forma ordenada de realizar operaciones en matrices como sumar, multiplicar dos matrices de una manera “pitónica de una línea”.

Gracias

avatar de usuario
dkatzel

Hay nuevos métodos añadidos a java.util.Arrays para convertir una matriz en un flujo de Java 8 que luego se puede usar para sumar, etc.

int sum =  Arrays.stream(myIntArray).sum();

Multiplicar dos matrices es un poco más difícil porque no puedo pensar en una forma de obtener el valor Y el índice al mismo tiempo que una operación Stream. Esto significa que probablemente tenga que transmitir los índices de la matriz.

//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...
 
int[] result = new int[a.length];

IntStream.range(0, a.length).forEach(i -> result[i] = a[i] * b[i]);

El comentarista @Holger señala que puede usar el map método en lugar de forEach Me gusta esto:

int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();

  • int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();

    – Holger

    24 de junio de 2014 a las 16:33

  • @Holger sí, eso también funcionaría. Aunque probablemente quieras usar mapToInt para evitar el boxeo.

    – dkatzel

    24 de junio de 2014 a las 16:43

  • Eso último equivale a una simulación de zip donde debe preasignar almacenamiento para el resultado. Me pregunto por qué no hay zip en la biblioteca de Streams.

    – Cabaña Reb

    20 de agosto de 2015 a las 15:19

  • De acuerdo con esta respuesta SO, un zip estaba en una versión beta anterior de Java 8, luego se eliminó. Afortunadamente, el cartel tenía la fuente y está en la respuesta. He usado el código varias veces y parece funcionar muy bien.

    – sparc_spread

    3 mayo 2016 a las 17:29


  • @dkatzel: dado que ya es un IntStream, el “mapa” toma un IntUnaryOperator, por lo que no hay boxeo involucrado.

    – M. Justin

    15 de febrero de 2017 a las 2:12


avatar de usuario
ian caballero

Puede convertir una matriz en una secuencia utilizando Arrays.stream():

int[] ns = new int[] {1,2,3,4,5};
Arrays.stream(ns);

Una vez que tenga su transmisión, puede usar cualquiera de los métodos descritos en la documentaciónme gusta sum() o lo que sea. Puede map o filter como en Python llamando a los métodos de transmisión relevantes con una función Lambda:

Arrays.stream(ns).map(n -> n * 2);
Arrays.stream(ns).filter(n -> n % 4 == 0);

Una vez que haya terminado de modificar su transmisión, llame toArray() para convertirlo de nuevo en una matriz para usar en otro lugar:

int[] ns = new int[] {1,2,3,4,5};
int[] ms = Arrays.stream(ns).map(n -> n * 2).filter(n -> n % 4 == 0).toArray();

Tenga cuidado si tiene que tratar con números grandes.

int[] arr = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
long sum = Arrays.stream(arr).sum(); // Wrong: sum == 0

La suma anterior no es 2 * Integer.MIN_VALUE. Tienes que hacer esto en este caso.

long sum = Arrays.stream(arr).mapToLong(Long::valueOf).sum(); // Correct

Tenga en cuenta que Arrays.stream (arr) crea un LongStream (o IntStream, …) en lugar de Stream, por lo que la función de mapa no se puede usar para modificar el tipo. Es por eso que se proporcionan las funciones .mapToLong, mapToObject, ….

Eche un vistazo a por qué no puedo asignar números enteros a cadenas cuando se transmite desde una matriz

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad