web-dev-qa-db-fra.com

Comment faire la somme des valeurs dans une carte avec un flux?

Je veux l'équivalent de cela avec un flux:

public static <T extends Number> T getSum(final Map<String, T> data) {
    T sum = 0;
    for (String key: data.keySet())
        sum += data.get(key);
    return sum;
}

Ce code ne compile pas réellement car 0 ne peut pas être affecté au type T, mais vous avez l’idée.

32
Jay

Tu peux le faire:

int sum = data.values().stream().mapToInt(Integer::parseInt).sum();
63
Paul Boddington

Voici une autre façon de faire ceci:

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

(Pour une somme juste int, cependant, la réponse de Paul fait moins de boxe et de déballage.)

Pour ce qui est de faire cela de manière générique , je ne pense pas qu’il existe un moyen beaucoup plus pratique.

Nous pourrions faire quelque chose comme ça:

static <T> T sum(Map<?, T> m, BinaryOperator<T> summer) {
    return m.values().stream().reduce(summer).get();
}

int sum = MyMath.sum(data, Integer::sum);

Mais vous finissez toujours par passer l'été. reduce est également problématique car il renvoie Optional. La méthode sum ci-dessus lève une exception pour une carte vide, mais une somme vide devrait être 0. Bien sûr, nous pourrions également passer le 0:

static <T> T sum(Map<?, T> m, T identity, BinaryOperator<T> summer) {
    return m.values().stream().reduce(identity, summer);
}

int sum = MyMath.sum(data, 0, Integer::sum);
12
Radiodef

Vous pouvez le faire comme ça:

int creditAmountSum = result.stream().map(e -> e.getCreditAmount()).reduce(0, (x, y) -> x + y);
1
Saeed Zarinfam