polinomios - sumar elementos de un arraylist java
¿Cómo sumar una lista de enteros con flujos de Java? (10)
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();
De los docs
Operaciones de reducción Una operación de reducción (también llamada pliegue) toma una secuencia de elementos de entrada y los combina en un solo resultado de resumen mediante la aplicación repetida de una operación de combinación, como encontrar la suma o el máximo de un conjunto de números, o acumular elementos en una lista. Las clases de secuencias tienen múltiples formas de operaciones de reducción generales, llamadas reduce () y collect (), así como múltiples formas de reducción especializadas como sum (), max () o count ().
Por supuesto, tales operaciones pueden implementarse fácilmente como simples bucles secuenciales, como en:
int sum = 0; for (int x : numbers) { sum += x; }
Sin embargo, hay buenas razones para preferir una operación de reducción sobre una acumulación mutativa como la anterior. Una reducción no solo es "más abstracta": opera en la secuencia como un todo en lugar de elementos individuales, sino que una operación de reducción construida adecuadamente es inherentemente paralelizable, siempre que las funciones utilizadas para procesar los elementos sean asociativas y apátrida. Por ejemplo, dada una secuencia de números para los que queremos encontrar la suma, podemos escribir:
int sum = numbers.stream().reduce(0, (x,y) -> x+y);
o:
int sum = numbers.stream().reduce(0, Integer::sum);
Estas operaciones de reducción pueden ejecutarse de forma segura en paralelo casi sin modificaciones:
int sum = numbers.parallelStream().reduce(0, Integer::sum);
Entonces, para un mapa usarías:
integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);
O:
integers.values().stream().reduce(0, Integer::sum);
Esta sería la forma más corta de resumir la matriz de tipo
int
(para
LongStream
matriz
LongStream
, para
DoubleStream
matriz
double
y así sucesivamente).
Sin embargo, no todos los tipos primitivos de entero o coma flotante tienen la implementación
Stream
.
IntStream.of(integers).sum();
Esto funcionará, pero el
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:
integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
He declarado una lista de enteros.
ArrayList<Integer> numberList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
Puede intentar usar estas diferentes formas a continuación.
Usando
mapToInt
int sum = numberList.stream().mapToInt(Integer::intValue).sum();
Usando
summarizingInt
int sum = numberList.stream().collect(Collectors.summarizingInt(Integer::intValue)).getSum();
Usando
reduce
int sum = numberList.stream().reduce(Integer::sum).get().intValue();
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 existe soporte de flujo especializado). Por ejemplo, stram con BigInteger Para tal tipo, podemos usar la operación de reducción como
list.stream (). reduce ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))
Puede usar
reduce()
para sumar una lista de enteros.
int sum = integers.values().stream().reduce(0, Integer::sum);
Puede usar el método de recopilación para agregar una lista de enteros.
List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
Puede usar el método de reducción:
long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);
o
long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);
Sugiero 2 opciones más:
integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));
El segundo usa el
Collectors.summingInt()
, también hay un colector
summingLong()
que
mapToLong
con
mapToLong
.
Y una tercera opción: Java 8 presenta un acumulador
LongAdder
muy eficaz diseñado para acelerar el resumen en flujos paralelos y entornos de subprocesos múltiples.
Aquí, aquí hay un ejemplo de uso:
LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
class Pojo{
int num;
public Pojo(int num) {
super();
this.num = num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
List<Pojo> list = new ArrayList<Pojo>();
list.add(new Pojo(1));
list.add(new Pojo(5));
list.add(new Pojo(3));
list.add(new Pojo(4));
list.add(new Pojo(5));
int totalSum = list.stream().mapToInt(pojo -> pojo.getNum()).sum();
System.out.println(totalSum);