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();
java
java-8
java-stream
Mitgliedssound
quelle
quelle
mapToLong
, um Überläufe zu vermeiden, abhängig von den Werten, die Ihre Karte haben kann.i -> i
persönlich sehr klar. Nun ja, Sie müssen wissen, dass der Wert automatisch entpackt wird, aber es ist wahr seit Java 5 ...foo(int i)
schreiben nichtfoo(myInteger.intValue());
jedes Mal , wenn sie sie aufrufen (oder zumindest erwarte ich das nicht !!). Ich stimme Ihnen zu, dasInteger::intValue
ist expliziter, aber ich denke, das gilt auch hier. Die Leute sollten es nur einmal lernen und dann bist du fertig :-). Es ist nicht so, als wäre es eine magische Verschleierung.i -> i
sieht aus wie ein no-op und konzeptuell, es ist ein No-op. Sicher, unter der HaubeInteger.intValue()
wird aufgerufen, aber noch tiefer unter der Haube werden diese Methoden eingefügt, um genau das No-Op zu werden, wie es im Quellcode aussieht.Integer::intValue
hat den Bonuspunkt, keine synthetische Methode im Bytecode zu erstellen, aber es ist nicht das, was Ihre Entscheidung über die Organisation Ihres Quellcodes beeinflussen sollte.Antworten:
Dies wird funktionieren, aber das
i -> i
macht ein automatisches Unboxing, weshalb es sich seltsam "anfühlt". Beides funktioniert und erklärt besser, was der Compiler unter der Haube mit Ihrer ursprünglichen Syntax tut:quelle
BigDecimal sum = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
Ich schlage 2 weitere Optionen vor:
Der zweite verwendet
Collectors.summingInt()
Collector, es gibt auch einensummingLong()
Collector, mit dem Sie verwenden würdenmapToLong
.Und eine dritte Option: Java 8 führt einen sehr effektiven
LongAdder
Akkumulator ein, der die Zusammenfassung in parallelen Streams und Multithread-Umgebungen beschleunigt. Hier ist ein Beispiel:quelle
Aus den Dokumenten
Für eine Karte würden Sie also Folgendes verwenden:
Oder:
quelle
Sie können die Reduzierungsmethode verwenden:
oder
quelle
int
, es istInteger::sum
Long::sum
alsInteger::sum
.Sie können
reduce()
eine Liste von Ganzzahlen summieren.quelle
Mit der Methode collect können Sie eine Liste von Ganzzahlen hinzufügen.
quelle
Dies wäre der kürzeste Weg, um den
int
Typ Array (fürlong
ArrayLongStream
, fürdouble
ArrayDoubleStream
usw.) zusammenzufassen. Allerdings haben nicht alle primitiven Ganzzahl- oder Gleitkommatypen dieStream
Implementierung.quelle
IntStream.of()
wird es für dieses Problem nicht funktionieren, es sei denn, wir machen so etwas Gruseliges:IntStream.of( integers.values().stream().mapToInt( Integer::intValue ).toArray() ).sum();
integers.values().stream().mapToInt( Integer::intValue ).sum()
.Möge dies denen helfen, die Objekte auf der Liste haben.
Wenn Sie eine Liste von Objekten haben und bestimmte Felder dieses Objekts summieren möchten, verwenden Sie Folgendes.
quelle
Ich habe eine Liste von Ganzzahlen deklariert.
Sie können diese verschiedenen Methoden unten verwenden.
Verwenden von
mapToInt
Verwenden von
summarizingInt
Verwenden von
reduce
quelle
quelle
Die meisten Aspekte werden behandelt. Es könnte jedoch erforderlich sein, die Aggregation anderer Datentypen außer Integer, Long (für die bereits spezielle Stream-Unterstützung vorhanden ist) zu finden. Zum Beispiel stram mit BigInteger Für einen solchen Typ können wir Reduktionsoperationen wie verwenden
list.stream (). redu ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))
quelle