Find Duplicate Elements Using HashMap in Java
Problem
Tallying every value in a HashMap first, then keeping only the entries whose count is above one, separates 'how often does this appear' from 'which ones repeat'.
Given an array of integers, use a HashMap to find every value that appears more than once.
Java Program
import java.util.LinkedHashMap;
import java.util.Map;
public class DuplicateFinderHashMap {
public static void main(String[] args) {
int[] nums = {2, 7, 4, 7, 9, 2, 6};
Map<Integer, Integer> tally = new LinkedHashMap<>();
for (int num : nums) {
tally.put(num, tally.getOrDefault(num, 0) + 1); // read-or-default, then store the incremented count
}
StringBuilder duplicates = new StringBuilder();
for (Map.Entry<Integer, Integer> entry : tally.entrySet()) {
if (entry.getValue() > 1) { // appeared more than once
if (duplicates.length() > 0) duplicates.append(", ");
duplicates.append(entry.getKey());
}
}
System.out.println("Duplicates: " + duplicates);
}
}Output
Core Logic
Building a full tally of every value first, then filtering that tally down to the entries with a count above one, reuses the same map for both counting and detecting.
- 1A
LinkedHashMap<Integer, Integer>namedtallyrecords each value's count, in the order values were first seen. - 2
tally.getOrDefault(num, 0)reads a value's running count, defaulting to0on its first appearance, andput()stores it back incremented. - 3Once the array has been fully tallied,
entrySet()is walked once more, checkingentry.getValue() > 1for each value. - 4Every value whose count exceeds one is appended to the result, in the order it was first encountered.
[2, 7, 4, 7, 9, 2, 6], 4, 9, and 6 each appear once, while 2 and 7 each appear twice — so the values reported are 2, 7.Key Point: The tally map is doing double duty here — the exact same structure that counts occurrences also answers 'does this repeat', just by checking whether a count is above one.
Why: Building the tally visits every element once and holds one entry per distinct value, up to n in the worst case.
Key Concepts
Approach 2: Java 8
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class DuplicateFinderStream {
public static void main(String[] args) {
int[] nums = {2, 7, 4, 7, 9, 2, 6};
// Tallies every value, then keeps only the ones that appeared more than once
String duplicates = Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(n -> n, LinkedHashMap::new, Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() > 1)
.map(e -> String.valueOf(e.getKey()))
.collect(Collectors.joining(", "));
System.out.println("Duplicates: " + duplicates);
}
}
Output
Core Logic
Grouping the array's values with counting(), then filtering that tally down to counts above one, expresses the same two-step idea — tally, then filter — as a single pipeline.
- 1
Arrays.stream(nums).boxed()turns theint[]into aStream<Integer>, sincegroupingBy()needs reference types. - 2
Collectors.groupingBy(n -> n, LinkedHashMap::new, Collectors.counting())tallies every value, keeping first-seen order via theLinkedHashMapfactory. - 3
.entrySet().stream().filter(e -> e.getValue() > 1)keeps only the entries whose tally exceeds one. - 4
.map(Map.Entry::getKey)andCollectors.joining(", ")extract just the repeated keys and join them into the final printed string.
[2, 7, 4, 7, 9, 2, 6], grouping and filtering finds that only 2 and 7 have a tally above one, joining them into "2, 7".Key Point: This is the same 'tally, then filter' idea as the primary approach, expressed as a pipeline instead of two explicit loops — the tally map is still built in full before the filtering step runs.
Why: groupingBy() visits every element once to build the tally, and the filter/map/join steps afterward each pass over the map's entries, which number at most n.