Find Duplicate Elements in Java
Problem
A duplicate element is one that appears two or more times in an array, as opposed to an element that appears exactly once.
Given an array of integers, find every element that appears more than once.
Java Program
import java.util.LinkedHashMap;
import java.util.Map;
public class FindDuplicateElements {
public static void main(String[] args) {
int[] arr = {5, 3, 8, 3, 9, 5, 1};
Map<Integer, Integer> freq = new LinkedHashMap<>();
for (int num : arr) {
// getOrDefault(num, 0) reads the current count, or 0 if unseen, then increments it
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
StringBuilder duplicates = new StringBuilder();
for (Map.Entry<Integer, Integer> entry : freq.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 frequency map first, then keeping only the entries with a count greater than one, separates 'how often' from 'which ones repeat'.
- 1A
LinkedHashMap<Integer, Integer>namedfreqtracks each element's count, preserving the order elements were first seen. - 2
freq.getOrDefault(num, 0)reads the current count, or0if unseen, thenfreq.put(num, ...)stores the incremented count. - 3After the full scan,
entrySet()is walked once more, checkingentry.getValue() > 1for each element. - 4Every element whose count exceeds one is appended to the result, in the order it was first seen.
[5, 3, 8, 3, 9, 5, 1], 8, 9, and 1 each appear once, while 5 and 3 each appear twice — so the duplicates reported are 5, 3.Key Point: This is the same frequency map used to count how many times each element appears — finding duplicates is just a filter applied on top of it.
Why: Building the frequency map 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 FindDuplicateElementsStream {
public static void main(String[] args) {
int[] arr = {5, 3, 8, 3, 9, 5, 1};
Map<Integer, Long> freq = Arrays.stream(arr).boxed()
.collect(Collectors.groupingBy(num -> num, LinkedHashMap::new, Collectors.counting()));
// Keeps only the elements whose count is greater than one
String duplicates = freq.entrySet().stream()
.filter(e -> e.getValue() > 1)
.map(Map.Entry::getKey)
.map(String::valueOf)
.collect(Collectors.joining(", "));
System.out.println("Duplicates: " + duplicates);
}
}
Output
Core Logic
groupingBy plus counting() builds the same frequency map declaratively, and a stream filter keeps only the entries with a count above one.
- 1
Arrays.stream(arr).boxed()turns theint[]into aStream<Integer>. - 2
Collectors.groupingBy(num -> num, LinkedHashMap::new, Collectors.counting())groups equal elements and counts each group, in first-appearance order. - 3
freq.entrySet().stream().filter(e -> e.getValue() > 1)keeps only the entries whose count is greater than one. - 4
.map(Map.Entry::getKey)pulls just the element out of each surviving entry, andCollectors.joining(", ")joins them into the final result.
[5, 3, 8, 3, 9, 5, 1] and filtering for counts above one keeps 5 and 3, the same duplicates the manual version found.Key Point: The filter condition — count > 1 — is the exact same rule the manual version's second loop checks, just expressed as a stream predicate instead of an if statement.
Why: groupingBy() still visits every element once while building the map, which holds one entry per distinct value just like the manual version.