web-dev-qa-db-fra.com

Comment faire la somme d'une liste d'entiers avec des flux Java?

Je veux résumer une liste d'entiers. Cela fonctionne comme suit, mais la syntaxe ne semble pas correcte. Le code pourrait-il être optimisé?

Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
326
membersound

Cela fonctionnera, mais le i -> i effectue un unboxing automatique, raison pour laquelle il se sent "étrange". L'une ou l'autre des solutions suivantes fonctionnera et expliquera mieux ce que le compilateur fait sous le capot avec votre syntaxe d'origine:

integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
451
Necreaux

Je suggère 2 autres options:

integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));

Le second utilise Collectors.summingInt() collecteur. Il existe également un collecteur summingLong() que vous utiliseriez avec mapToLong.


Et une troisième option: Java 8 introduit un accumulateur très efficace LongAdder , conçu pour accélérer la synthèse dans des flux parallèles et des environnements multi-thread. Ici, voici un exemple d'utilisation:

LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
141
Alex Salauyou

De la docs

Opérations de réduction Une opération de réduction (également appelée pli) prend une séquence d’éléments d’entrée et les combine en un résultat résumé unique en appliquant plusieurs fois une opération de combinaison, par exemple en recherchant la somme ou le maximum d’un ensemble de nombres, ou en accumulant des éléments. une liste. Les classes de flux ont plusieurs formes d'opérations de réduction générales, appelées reduction () et collect (), ainsi que plusieurs formes de réduction spécialisées telles que sum (), max () ou count ().

Bien entendu, de telles opérations peuvent être facilement mises en œuvre sous forme de simples boucles séquentielles, comme dans:

int sum = 0;
for (int x : numbers) {
   sum += x;
}

Cependant, il y a de bonnes raisons de préférer une opération réduite à une accumulation mutante telle que ci-dessus. Non seulement une réduction est "plus abstraite" - elle agit sur le flux dans son ensemble plutôt que sur des éléments individuels -, mais une opération de réduction correctement construite est par nature parallélisable, tant que la ou les fonctions utilisées pour traiter les éléments sont associatives. et apatride. Par exemple, étant donné un flux de nombres pour lequel nous voulons trouver la somme, nous pouvons écrire:

int sum = numbers.stream().reduce(0, (x,y) -> x+y);

ou:

int sum = numbers.stream().reduce(0, Integer::sum);

Ces opérations de réduction peuvent se dérouler en toute sécurité en parallèle sans presque aucune modification:

int sum = numbers.parallelStream().reduce(0, Integer::sum);

Donc, pour une carte que vous utiliseriez:

integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);

Ou:

integers.values().stream().reduce(0, Integer::sum);
80
J Atkin

Vous pouvez utiliser la méthode de réduction:

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);

ou

long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);
26
Saeed Zarinfam

Vous pouvez utiliser reduce() pour résumer une liste d'entiers.

int sum = integers.values().stream().reduce(0, Integer::sum);
15
Johnson Abraham

Vous pouvez utiliser la méthode collect pour ajouter une liste d'entiers.

List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
11
Ashish Jha

Ce serait le moyen le plus rapide de résumer le tableau de type int (pour long tableau LongStream, pour double tableau DoubleStream, etc.). Cependant, tous les types entiers primitifs ou à virgule flottante n'ont pas l'implémentation Stream.

IntStream.of(integers).sum();
3
Sachith Dickwella

J'ai déclaré une liste de nombres entiers.

ArrayList<Integer> numberList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));

Vous pouvez essayer d'utiliser ces différentes manières ci-dessous.

Utiliser mapToInt

int sum = numberList.stream().mapToInt(Integer::intValue).sum();

Utiliser summarizingInt

int sum = numberList.stream().collect(Collectors.summarizingInt(Integer::intValue)).getSum();

Utiliser reduce

int sum = numberList.stream().reduce(Integer::sum).get().intValue();
0
JDGuide