# Perils of duplicate finding

DevFeed: [Perils of duplicate finding](<https://devfeed.tech/articles/perils-of-duplicate-finding-20952.md>)

Original publisher: [Read original article](<https://jakewharton.com/perils-of-duplicate-finding/>)

Published: 2024-02-14T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [refactor](<https://devfeed.tech/tags/refactor.md>)

## AI overview

A Kotlin article examines several ways to find duplicated integers in a collection. It explains why collection subtraction and MutableList.removeAll produce unexpected results, then refactors toward approaches that correctly track previously seen values.

## Source excerpt

Given an array of integers ([1, 2, 3, 1, 3, 1]), find the elements which are duplicated. No, we're not interviewing. I'm trying to prevent a user from specifying a reserved value twice. Elsewhere in the file I already have duplicate detection for object tags. val dupes: Map<Int, List<Widget>> = widgets.groupBy(Widget::tag) .filterValues { it.size > 1 } I can do the same technique for the integer array with an identity function and grabbing the resulting keys. val dupes: Set<Int> = ints.groupBy { it } .filterValues { it.size > 1 } .keys This prints [1, 3]. So... done? Yes! But no, using the map seems wasteful, right? Attempt 1 My first attempt to avoid the map was to remove the set of integers from a list of them. This should result in a list of any duplicated elements. val dupes: List<Int> = ints.toList() - ints.toSet() No matter the content of ints, this will always print []. Why? The minus operator says that it "returns a list containing all elements of the original collection except the elements contained in the given elements collection". So it removes all occurrences of each element in the set from the list. This is some surprising behavior to hide behind an operator whose signature operates on an Iterable receiver and Collection argument. Attempt 2 Second attempt switches to MutableList.removeAll which takes a collection of elements. The MutableList.remove function only removes the first occurrence of an element, so this should remove the first occurrence of each element in the set. val dupes: List<Int> = ints.toMutableList() .apply { removeAll(ints.toSet()) } This once again prints []. But why? Kotlin made me a liar. MutableList.remove does indeed only remove the first occurrence of the element. MutableList.removeAll, however, removes all occurrences of each element in the supplied collection. That's quite the subtle asymmetry. There is no function for removing all occurrences of a single element. Nor a function to remove only the first occurrences of each elem