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();
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();
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();
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);
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);
Vous pouvez utiliser reduce()
pour résumer une liste d'entiers.
int sum = integers.values().stream().reduce(0, Integer::sum);
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));
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();
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();