Quiero resumir una lista de enteros. Funciona de la siguiente manera, pero la sintaxis no se siente bien. ¿Se podría optimizar el código?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
java
java-8
java-stream
miembros
fuente
fuente
mapToLong
para evitar desbordamientos, dependiendo de los valores que pueda tener su mapa.i -> i
muy claro, personalmente. Bueno, sí, necesita saber que el valor se desempaquetará automáticamente, pero es cierto desde Java 5 ...foo(int i)
no escribenfoo(myInteger.intValue());
cada vez que lo llaman (¡o al menos espero que no!). Estoy de acuerdo con usted en queInteger::intValue
es más explícito, pero creo que lo mismo se aplica aquí. La gente debería aprenderlo una vez y listo :-). No es como si fuera una ofuscación mágica.i -> i
parece un no-op y, conceptualmente, es un no-op. Claro, bajo el capóInteger.intValue()
se llama, pero aún más profundo bajo el capó, esos métodos se alinean para convertirse exactamente en el no-op que parece en el código fuente.Integer::intValue
tiene el punto extra de no crear un método sintético en el código de bytes, pero no es lo que debe impulsar su decisión de cómo organizar su código fuente.Respuestas:
Esto funcionará, pero
i -> i
está haciendo un unboxing automático, por lo que "se siente" extraño. Cualquiera de los siguientes funcionará y explicará mejor lo que el compilador está haciendo bajo el capó con su sintaxis original:fuente
BigDecimal sum = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
Sugiero 2 opciones más:
El segundo usa el
Collectors.summingInt()
colector, también hay unsummingLong()
colector con el que usaríasmapToLong
.Y una tercera opción: Java 8 presenta un
LongAdder
acumulador muy eficaz diseñado para acelerar el resumen en flujos paralelos y entornos de subprocesos múltiples. Aquí, aquí hay un ejemplo de uso:fuente
De los documentos
Entonces, para un mapa usarías:
O:
fuente
Puede usar el método de reducción:
o
fuente
int
, esInteger::sum
Long::sum
queInteger::sum
.Puede usar
reduce()
para sumar una lista de enteros.fuente
Puede usar el método de recopilación para agregar una lista de enteros.
fuente
Esta sería la forma más corta de resumir el
int
tipo de matriz (paralong
matrizLongStream
, paradouble
matriz,DoubleStream
etc.). SinStream
embargo, no todos los tipos primitivos de entero o coma flotante tienen la implementación.fuente
IntStream.of()
lo tanto , no funcionará para este problema, a menos que estemos creando algo espeluznante como este:IntStream.of( integers.values().stream().mapToInt( Integer::intValue ).toArray() ).sum();
integers.values().stream().mapToInt( Integer::intValue ).sum()
.Que esto ayude a aquellos que tienen objetos en la lista.
Si tiene una lista de objetos y desea sumar campos específicos de este objeto, use lo siguiente.
fuente
He declarado una lista de enteros.
Puede intentar usar estas diferentes formas a continuación.
Utilizando
mapToInt
Utilizando
summarizingInt
Utilizando
reduce
fuente
fuente
La mayoría de los aspectos están cubiertos. Pero podría haber un requisito para encontrar la agregación de otros tipos de datos aparte de Integer, Long (para el cual ya está presente el soporte de flujo especializado). Por ejemplo, Stram con BigInteger. Para este tipo, podemos utilizar la operación de reducción como
list.stream (). reduce ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))
fuente