it-swarm.com.de

Wie summiere ich eine Liste von Ganzzahlen mit Java Streams?

Ich möchte eine Liste von ganzen Zahlen zusammenfassen. Es funktioniert wie folgt, aber die Syntax fühlt sich nicht richtig an. Könnte der Code optimiert werden?

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

Dies wird funktionieren, aber der i -> i führt ein automatisches Unboxing durch, weshalb es sich seltsam "anfühlt". Beide der folgenden Methoden funktionieren und erläutern besser, was der Compiler unter der Haube mit Ihrer ursprünglichen Syntax tut:

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

Ich schlage 2 weitere Optionen vor:

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

Der zweite verwendet Collectors.summingInt() collector, es gibt auch einen summingLong() collector, den Sie mit mapToLong verwenden würden.


Und eine dritte Option: Java 8 führt einen sehr effektiven LongAdder -Akkumulator ein, der entwickelt wurde, um die Zusammenfassung in parallelen Streams und Multithread-Umgebungen zu beschleunigen. Hier ist ein Beispiel:

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

Aus dem docs

Reduktionsoperationen Eine Reduktionsoperation (auch Fold genannt) nimmt eine Folge von Eingabeelementen auf und kombiniert sie durch wiederholte Anwendung einer Kombinationsoperation zu einem einzigen zusammenfassenden Ergebnis, z eine Liste. Die Streams-Klassen verfügen über mehrere Formen allgemeiner Reduktionsoperationen, die als redu- zieren () und sammeln () bezeichnet werden, sowie über mehrere spezialisierte Reduktionsformen wie sum (), max () oder count ().

Natürlich können solche Operationen leicht als einfache sequentielle Schleifen implementiert werden, wie in:

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

Es gibt jedoch gute Gründe, eine Reduktionsoperation einer mutativen Anhäufung wie der obigen vorzuziehen. Eine Reduktion ist nicht nur "abstrakter" - sie wird auf den gesamten Stream angewendet und nicht auf einzelne Elemente -, sondern eine ordnungsgemäß konstruierte Reduktionsoperation ist von Natur aus parallelisierbar, solange die zur Verarbeitung der Elemente verwendeten Funktionen assoziativ sind und staatenlos. Wenn wir beispielsweise einen Zahlenstrom angeben, für den wir die Summe ermitteln möchten, können wir schreiben:

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

oder:

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

Diese Reduktionsvorgänge können nahezu unverändert sicher parallel ausgeführt werden:

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

Für eine Karte würden Sie also Folgendes verwenden:

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

Oder:

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

Sie können die Reduktionsmethode verwenden:

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

oder

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

Sie können reduce() verwenden, um eine Liste von ganzen Zahlen zu summieren.

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

Mit der collect-Methode können Sie eine Liste von ganzen Zahlen hinzufügen.

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

Dies wäre der kürzeste Weg, um ein Array vom Typ int zusammenzufassen (für long Array LongStream, für double Array DoubleStream usw.). Nicht alle primitiven Ganzzahl- oder Gleitkommatypen haben jedoch die Implementierung Stream.

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

Ich habe eine Liste von ganzen Zahlen deklariert.

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

Sie können diese verschiedenen Methoden unten ausprobieren.

mapToInt verwenden

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

summarizingInt verwenden

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

reduce verwenden

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