Quiero obtener todos los valores duplicados de varias listas de enteros. La parte confusa es que esta lista de enteros está dentro de un mapa de mapa como este LinkedHashMap<String, LinkedHashMap<String, List>> streams
// sample value { break_desc100= { bDesc_1000=[62, 72, 82, 92, 102, 112, 122], bDesc 1001=[180, 190, 200, 210, 220, 230, 240], cMessage_1000=[112], cMessage_1001=[232] } } // for this one I want to get 112Hasta ahora, intenté usar RetainAll, pero mi código no funciona si la lista con duplicados no está una al lado de la otra.
for (Map.Entry<String,LinkedHashMap<String,List<Integer>>> entry : streams.entrySet()) { String currentStream = entry.getKey(); LinkedHashMap<String,List<Integer>> bDescList = entry.getValue(); for (Map.Entry<String,List<Integer>> bDesc : bDescList.entrySet()) { if (firstIteration) { prevBDesc = bDesc; firstIteration = false; } else { List<Integer> currentList = prevBDesc.getValue(); List<Integer> nextList = bDesc.getValue(); duplicates = new ArrayList<Integer>(currentList); duplicates.retainAll(nextList); allDuplicates.addAll(duplicates); //Set<Integer> prevBDesc = bDesc; } } }EDITAR: Lo siento, chicos, olvidé agregar que se está ejecutando en Java 1.5.
Esto supone que está buscando valores duplicados. Esto incluye encontrar duplicados en la misma lista. Corrígeme si entendí mal la pregunta.
Podría hacer esto en el tiempo O(N) y en el espacio O(N) recorriendo el hash anidado mientras cuenta las ocurrencias de cada entero. Entonces podemos filtrar a enteros con más de una ocurrencia.
Map<String, List<Integer>> innerMap = new HashMap<>(); innerMap.put("bDesc_1000", Arrays.asList(62, 72, 82, 92, 102, 112, 122)); innerMap.put("bDesc_1001", Arrays.asList(180, 190, 200, 210, 220, 230, 240)); innerMap.put("cMessage_1000", Collections.singletonList(112)); innerMap.put("cMessage_1001", Collections.singletonList(232)); Map<String, Map<String, List<Integer>>> map = new HashMap<>(); map.put("break_desc100", innerMap); Map<Integer, Integer> occurrenceMap = new HashMap<>(); map.forEach((outerKey, outerValue) -> { outerValue.forEach((innerKey, innerValue) -> { innerValue.forEach((element -> occurrenceMap.merge(element, 1, Integer::sum) )); }); }); List<Integer> duplicates = occurrenceMap.entrySet().stream() .filter(e -> e.getValue() > 1) .map(Map.Entry::getKey) .collect(Collectors.toList()); System.out.println(duplicates);producción
[112]Esto parece una tarea adecuada para flujos:
Map<Integer, Long> counts = streams.values().stream() .flatMap(bDescList -> bDescList.values().stream()) .flatMap(nextList -> nextList.stream()) .collect(Collectors.groupingBy( Function.identity(), Collectors.counting())); counts.values().removeIf(c -> c == 1L); Set<Integer> duplicates = counts.keySet(); Este código primero crea un mapa de conteos. Para esto, primero transmite los valores del mapa externo y luego usa Stream.flatMap para crear una nueva transmisión con los valores de todos los mapas internos. Como estos valores son en realidad listas, necesitamos usar Stream.flatMap nuevamente, para finalmente obtener una secuencia de Integer . (He guardado los nombres de las variables de su pregunta).
Recolectamos a un mapa de conteos, donde las claves son los números de todos los valores de lista de los mapas internos, y los valores son los conteos para cada uno de estos números, en todos los mapas y listas.
Luego, eliminamos todas las entradas del mapa de recuentos que tengan un valor de 1 . Las claves restantes son los números duplicados.
EDITAR: Aquí está el código equivalente en Java 5... 😨😨😨
Map<Integer, Long> counts = new HashMap<Integer, Long>(); for (Map<String, List<Integer>> bDescList : streams.values()) { for (List<Integer> bDesc : bDescList.values()) { for (Integer n : bDesc) { Long c = counts.get(n); if (c == null) { c = 0L; } counts.put(n, c + 1); } } } Iterator<Long> it = counts.values().iterator(); while (it.hasNext()) { Long c = it.next(); if (c == 1L) { it.remove(); } } Set<Integer> duplicates = counts.keySet();El razonamiento es exactamente el mismo aquí... Creamos un mapa de recuentos iterando el mapa de mapas de listas, luego eliminamos las entradas con un recuento de 1 y las claves restantes son los duplicados.