Find duplicates in java list
Duplicate elements in a list means the elements which occur more than once.
In this article, we will understand different ways to achieve this including those added in java 8.
Below is the algorithm for this method to find duplicate elements in a list in java.
- Create a new java Set object and a new arraylist to hold duplicate elements.
- Iterate or loop through the list.
- For each element in the list, add it to the Set using its
add()
method.
add() returns true, if the element is added and false, if the element was already present in the set. - Therefore, if the element is already in the Set, it is a duplicate.
So, we add it to the arraylist. - At the end of the iteration, the duplicate arraylist will contain all duplicate elements in the original list.
Example program based on this algorithm is as below
List<Integer> numbers = List.of(1, 2, 3, 4, 3, 1, 2); Set<Integer> set = new HashSet<>(); List<Object> duplicates = new ArrayList<>(); numbers.forEach(n -> { if (!set.add(n)) { duplicates.add(n); } }); System.out.println("Duplicate elements: " + duplicates);
Output is
Duplicate elements: [3, 1, 2]
Note that we have used java 8 forEach() method to iterate over the list but you can use any other way as well.
2. Using Map
Below are the steps of algorithm for this method.
- Create a new map object and a new arraylist to hold duplicate elements.
Keys of this map will be the elements of the original list and its values will be the count of their occurrence in the list. - Loop through the list.
- For each element in the list, check if it exists as a key in the Map using its
containsKey()
method. - If it exists, increment its value in the Map and add it again using
put()
method. - If it does not exist, add it to the Map with a value of 1.
- After the list iteration is complete, all the map elements with a value greater than 1 are duplicates.
- Finally, iterate over the map and add those elements whose value is greater than 1 to the list for holding duplicate elements.
Example program is as below
List<Integer> numbers = List.of(1, 2, 3, 4, 3, 1, 2); Map<Integer, Integer> countMap = new HashMap<>(); List<Object> duplicates = new ArrayList<>(); numbers.forEach(n -> { if (countMap.containsKey(n)) { countMap.put(n, countMap.get(n) + 1); } else { countMap.put(n, 1); } }); countMap.keySet().forEach(k -> { if(countMap.get(k)> 1) { duplicates.add(k); } });
If you are asked to find duplicate elements in a list without using any Collection classes such as Set or Map etc., then this method would be useful.
Algorithmic steps for this method are
- Loop through the list.
- For each element in the list, loop through the rest of the list.
- If the current loop element is equal to any of the remaining elements, it is a duplicate.
Program written as per these steps is as follows
List<Integer> numbers = List.of(1, 2, 3, 4, 3, 1, 2); List<Object> duplicates = new ArrayList<>(); for (int i = 0; i < numbers.size() - 1; i++) { for (int j = i + 1; j < numbers.size(); j++) { if (numbers.get(i).equals(numbers.get(j))) { duplicates.add(numbers.get(i)); } } }
4. Using java 8 streams
This method is based on java 8 streams and works on the below steps.
- Convert the list to a stream.
- Convert the stream to a
Map
usingcollect()
method such as the key is each element in the list and value is the number of occurrences. collect()
method returns aMap
and accepts a Collector as argument. Implementation of Collector determines the keys and values of the resultantMap
.
In this case, since we want the Map keys to be the list elements and its values to be the count of their occurrence, we can useCollectors.groupingBy()
to create a collector.- Once the Map is created with
groupingBy()
, use theentrySet()
method to get a set ofMap.Entry
objects. - Filter the entries based on the value (that is, number of occurrences) greater than 1.
- Map the filtered entries to their keys.
Example program is
List<Integer> numbers = List.of(1, 2, 3, 4, 3, 1, 2); Map<Object, Long> map = numbers. stream(). collect( Collectors. groupingBy(n -> n, Collectors.counting()) ); List<Object> duplicates = map. entrySet(). stream(). filter(e -> e.getValue() > 1). map(e -> e.getKey()). collect(Collectors.toList());
groupingBy()
is used to group elements of a collection based on some criteria.
Here’s how the groupingBy()
method works for this example:
- The criteria is supplied as a Lambda expression since
groupingBy()
accepts aFunction
argument, which is a functional interface.
In this case, we are grouping by the identity functionn -> n
, which means we are grouping the elements of the list by their values. - The second argument to
groupingBy()
is another collector that specifies how the elements in each group should be combined.
In this case, we are usingCollectors.counting()
, which creates aMap
that contains the count of each element in the list.
So, the resulting map will contain a count of how many times each element appears in the list.
We are then filter this map to find the elements that have a count greater than 1, which indicates that they are duplicates using filter() method.