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();
java
java-8
java-stream
membersound
la source
la source
mapToLong
pour éviter les débordements, selon les valeurs que votre carte peut avoir.i -> i
très clair, personnellement. Bon, oui il faut savoir que la valeur sera automatiquement déballée, mais c'est vrai depuis Java 5 ...foo(int i)
n'écrivent pas àfoo(myInteger.intValue());
chaque fois qu'ils l'appellent (ou du moins je m'attends à ce que non !!). Je suis d'accord avec vous, c'estInteger::intValue
plus explicite, mais je pense que la même chose s'applique ici. Les gens devraient juste l'apprendre une fois et vous avez terminé :-). Ce n'est pas comme si c'était de l'obscurcissement magique.i -> i
ressemble à un no-op et conceptuellement, il est un non-op. Bien sûr, sous le capotInteger.intValue()
est appelé, mais encore plus profondément sous le capot, ces méthodes sont intégrées pour devenir exactement le no-op auquel elles ressemblent dans le code source.Integer::intValue
a l'avantage de ne pas créer de méthode synthétique dans le code octet, mais ce n'est pas ce qui devrait motiver votre décision sur la façon d'organiser votre code source.Réponses:
Cela fonctionnera, mais le
i -> i
fait un déballage automatique, c'est pourquoi cela "semble" étrange. L'un des éléments suivants fonctionnera et expliquera mieux ce que le compilateur fait sous le capot avec votre syntaxe d'origine:la source
BigDecimal sum = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
Je suggère 2 options supplémentaires:
Le second utilise le
Collectors.summingInt()
collecteur, il y a aussi unsummingLong()
collecteur avec lequel vous utiliseriezmapToLong
.Et une troisième option: Java 8 introduit un très efficace
LongAdder
accumulateur conçu pour accélérer la synthèse dans des flux parallèles et des environnements multi-threads. Ici, voici un exemple d'utilisation:la source
À partir des documents
Donc, pour une carte que vous utiliseriez:
Ou:
la source
Vous pouvez utiliser la méthode de réduction:
ou
la source
int
, c'estInteger::sum
Long::sum
queInteger::sum
.Vous pouvez utiliser
reduce()
pour additionner une liste d'entiers.la source
Vous pouvez utiliser la méthode collect pour ajouter une liste d'entiers.
la source
Ce serait le moyen le plus court de résumer le
int
tableau de type (pourlong
tableauLongStream
, pourdouble
tableauDoubleStream
, etc.). Cependant, tous les types d'entiers primitifs ou à virgule flottante ne sont pasStream
implémentés.la source
IntStream.of()
, ne fonctionnera pas pour ce problème, sauf si nous faisons quelque chose de fantasmagorique comme ceci:IntStream.of( integers.values().stream().mapToInt( Integer::intValue ).toArray() ).sum();
integers.values().stream().mapToInt( Integer::intValue ).sum()
.Que cela aide ceux qui ont des objets sur la liste.
Si vous avez une liste d'objets et que vous souhaitez additionner des champs spécifiques de cet objet, utilisez ce qui suit.
la source
J'ai déclaré une liste d'entiers.
Vous pouvez essayer d'utiliser ces différentes méthodes ci-dessous.
En utilisant
mapToInt
En utilisant
summarizingInt
En utilisant
reduce
la source
la source
La plupart des aspects sont couverts. Mais il pourrait être nécessaire de trouver l'agrégation d'autres types de données en dehors d'Integer, Long (pour lequel un support de flux spécialisé est déjà présent). Par exemple, stram avec BigInteger Pour un tel type, nous pouvons utiliser réduire l'opération comme
list.stream (). réduire ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))
la source