Java 8 Collecteurs API


Cette question implique le mappage et le regroupement d'éléments à l'aide de collecteurs java 8. J'ai une liste de Patients. Chaque patient a une liste des départements qu'il a visités. Disons que je veux compter pour chaque département combien de fois il a été visité à l'aide de la nouvelle API collectors dans java 8, comment grouper par la liste des départements?

Merci!

REMARQUE: je sais que je peux mettre un compteur dans chaque département, cette question est uniquement dans le but d'apprendre la nouvelle java 8 caractéristiques.

Code:

public class Patient {
    private String id;
    private List<Department> history;
    /* some more getters/setters come here */
}

Dans ma méthode principale, j'ai une liste de Patients. Je veux savoir pour chaque département, combien de fois il a été visité, sans modifier la classe de département (ni l'étendre ou la décorer).

Je pense que je dois prendre un flux de patients et les mapper à une carte de dept- > count (combien de fois chaque patient a visité quel dept.). Avoir un flux de ces cartes-je n'ai aucune idée de ce qu'il faut faire pour regrouper ces cartes et les compter.

Author: Eugene Krapivin, 2014-04-26

1 answers

Tout d'abord, je suppose que si un Patient a visité un Service plus d'une fois, ce Service apparaîtra dans la liste des antécédents du Patient plus d'une fois.

Si c'est le cas, alors nous pouvons simplement prendre notre Flux de Patients et flatMap dans un Flux de Ministères, d'où l'apparition d'un Ministère indique une visite d'un Patient.

Ensuite, nous pouvons passer ceci au collecteur groupingBy. Nous voulons classer par département lui-même, donc la fonction de classificateur est l'identité fonction.

Pour la valeur, nous voulons mettre un 1 comme valeur si une entrée pour le Département n'est pas présent, mais nous voulons ajouter 1 à la valeur existante si une entrée est présente. Il y a un collecteur appelé counting() qui le fait déjà pour nous, donc nous le passons simplement en tant que collecteur en aval à groupingBy().

Le code résultant est le suivant:

import static java.util.stream.Collectors.*;

List<Patient> patients = ... ;

Map<Department, Long> frequency =
    patients.stream()
        .flatMap(p -> p.getHistory().stream())
        .collect(groupingBy(d -> d, counting()));

Notez que si un ministère n'a pas été visité, il sera tout simplement absent de la carte. Si vous avez une liste de départements, vous pouvez remplissez les valeurs zéro comme ceci:

departments.forEach(d -> frequency.putIfAbsent(d, 0L));

Ou si vous voulez remplir le zéro du côté get,

long numVisits = frequency.getOrDefault(dept, 0L);
 11
Author: Stuart Marks, 2014-04-26 01:34:42