I would like to retrieve duplicates from the list that only repeat x times. I don't know how to do it,I only managed to get all the duplicates.
CodePudding user response:
Count the frequencies for each element into a map Map<MyObject, Integer>
and then select the entries from the map by the required frequency.
Methods hashCode
and equals
MUST be properly implemented in the class MyObject
:
public static List<MyObject> findDuplicates(int frequency, List<MyObject> input) {
return input
.stream()
.collect(Collectors.groupingBy(x -> x, Collectors.summingInt(x -> 1))) // Map<MyObject, Integer>
.entrySet()
.stream() // Stream<Map.Entry<MyObject, Integer>>
.filter(e -> e.getValue() == frequency)
.map(Map.Entry::getKey) // Stream<MyObject>
.collect(Collectors.toList());
}
Non-stream implementation would be to build the frequency map and then iterate it to populate the filtered list and/or print the matching duplicated element:
public static List<MyObject> findDuplicates(int frequency, List<MyObject> input) {
Map<MyObject, Integer> frequencies = new LinkedHashMap<>();
for (MyObject mo : input) {
frequencies.merge(mo, 1, Integer::sum);
}
List<MyObject> result = new ArrayList<>();
frequencies.forEach((mo, freqValue) -> {
if (freqValue == frequency) {
result.add(mo);
// System.out.printlnm("Found: " mo);
}
});
return result;
}
CodePudding user response:
Here is a 3-line algorithm in pseudocode:
FOR each element "e" of collection "x"
INCREMENT the count for "e"
ENDFOR
We can implement this in Java many ways. For example, with a Map
:
public static <T> Map<T, Integer> countDuplicates(Collection<T> collection) {
Map<T, Integer> duplicateCounts = new HashMap<>();
for(T element : collection) {
// Map#putIfAbsent will put the entry (element, 1) iff the map does NOT already contain the key "element".
// If the map already contains the key "element", it returns the current value (element, ?).
Integer duplicateCount = duplicateCounts.putIfAbsent(element, 1);
if(duplicateCount != null) {
duplicateCounts.put(element, duplicateCount 1);
}
}
return duplicateCounts;
}