Digamos que tengo una List<Set<String>>
que se ve así:
[A,B,C,D] [B,C,D,E] [C,D,E,F] [D,E,F,G]
Si quiero usar cada valor (A,B,C,D,E,F,G) en cada Set<String>
en ese List<Set<String>>
y contar su ocurrencia mapeándolos, ¿cuál es una buena manera? para que yo lo implemente? Quiero hacer que la salida se vea algo como:
A: 1 B: 2 C: 3 D: 4 E: 3 F: 2 G: 1
Simplemente aplane la lista en una sola secuencia y use un recopilador groupingBy
.
groupingBy
crearía una lista y colocaría colisiones (los valores asociados con claves duplicadas) en la lista.Collectors.counting()
dice que si ve otra clave que ya está allí, simplemente mantenga un conteo y actualice el valor en 1. Entonces está contando las ocurrencias de las claves. 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);
Huellas dactilares
A=1 B=2 C=3 D=4 E=3 F=2 G=1
Aquí hay un ejemplo simple del comportamiento groupingBy
predeterminado. Simplemente pone los valores en una lista basada en sus restos al dividir por 10
. IntStream
genera una secuencia de int primitives
, por lo que deben convertirse en un objeto ( Integer
en este caso) para recopilarlos.
Map<Integer, List<Integer>> remainders = IntStream.range(0, 100).mapToObj(Integer::valueOf) .collect(Collectors.groupingBy(n -> n % 10)); remainders.entrySet().forEach(System.out::println);
huellas dactilares
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]
List<Set<String>> input = new ArrayList<>(); input.add(Set.of("A", "B", "C", "D")); input.add(Set.of("B", "C", "D", "E")); input.add(Set.of("C", "D", "E", "F")); input.add(Set.of("D", "E", "F", "G")); input.stream() .flatMap(Collection::stream) .collect(groupingBy(Function.identity(), counting())) .entrySet() .forEach(System.out::println);
importador
import java.util.*; import java.util.function.Function; import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy;
Usando Stream API, se debe usar flatMap
para conjuntos internos para obtener un flujo de cadenas y luego se construye un mapa de frecuencia:
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);
Producción:
A=1 B=2 C=3 D=4 E=3 F=2 G=1