Disons que j'ai une List<Set<String>> qui ressemble à ceci:
A: 1 B: 2 C: 3 D: 4 E: 3 F: 2 G: 1
Si je veux utiliser chaque valeur (A, B, C, D, E, F, G) dans chaque Set<String> dans cette List<Set<String>> et compter leur occurrence en les mappant, quel est un bon moyen pour moi de le mettre en œuvre? Je veux que la sortie ressemble à quelque chose comme:
[A,B,C,D] [B,C,D,E] [C,D,E,F] [D,E,F,G]
3 Réponses :
À l'aide de l'API Stream, flatMap pour les ensembles internes doit être utilisé pour obtenir un flux de chaînes, puis une carte de fréquence est créée:
A=1 B=2 C=3 D=4 E=3 F=2 G=1
Production:
List<Set<String>> data = Arrays.asList(
Set.of("A", "B", "C", "D"),
Set.of("B", "C", "D", "E"),
Set.of("C", "D", "E", "F"),
Set.of("D", "E", "F", "G")
);
data.stream()
.flatMap(Set::stream)
.collect(Collectors.toMap(s -> s, s -> 1, Integer::sum, LinkedHashMap::new))
.entrySet()
.forEach(System.out::println);
Aplatissez simplement la liste en un seul flux et utilisez un collecteur groupingBy .
groupingBy créerait une liste et mettrait les collisions (les valeurs associées aux clés en double) dans la liste.Collectors.counting() dit que si vous voyez une autre clé qui est déjà là, gardez simplement un compte et mettez à jour la valeur de 1. Vous comptez donc les occurrences des clés.0=[0, 10, 20, 30, 40, 50, 60, 70, 80, 90] 1=[1, 11, 21, 31, 41, 51, 61, 71, 81, 91] 2=[2, 12, 22, 32, 42, 52, 62, 72, 82, 92] 3=[3, 13, 23, 33, 43, 53, 63, 73, 83, 93] 4=[4, 14, 24, 34, 44, 54, 64, 74, 84, 94] 5=[5, 15, 25, 35, 45, 55, 65, 75, 85, 95] 6=[6, 16, 26, 36, 46, 56, 66, 76, 86, 96] 7=[7, 17, 27, 37, 47, 57, 67, 77, 87, 97] 8=[8, 18, 28, 38, 48, 58, 68, 78, 88, 98] 9=[9, 19, 29, 39, 49, 59, 69, 79, 89, 99]
Tirages
Map<Integer, List<Integer>> remainders =
IntStream.range(0, 100).mapToObj(Integer::valueOf)
.collect(Collectors.groupingBy(n -> n % 10));
remainders.entrySet().forEach(System.out::println);
Voici un exemple simple du comportement groupingBy par défaut. Il met simplement les valeurs dans une liste en fonction de leurs restes lors de la division par 10 . IntStream génère un flux de int primitives afin qu'elles doivent être converties en un objet ( Integer dans ce cas) pour être collectées.
A=1 B=2 C=3 D=4 E=3 F=2 G=1
impressions
List<Set<String>> list = List.of(Set.of("A", "B", "C", "D"),
Set.of("B", "C", "D", "E"),
Set.of("C", "D", "E", "F"),
Set.of("D", "E", "F", "G"));
Map<String, Long> freq =
list.stream().flatMap(Set::stream).collect(Collectors
.groupingBy(a -> a, Collectors.counting()));
freq.entrySet().forEach(System.out::println);
Fonctionne parfaitement, mais pouvez-vous m'aider à élaborer un peu sur l'algorithme que vous avez implémenté dans la partie .collect ()?
import java.util.*; import java.util.function.Function; import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy;