How to Find the Difference Between Two Lists in Kotlin
Kotlin's collection library gives you a one-symbol operator for list difference, which is convenient right up until one of your lists gets large - then the operator you reach for by default becomes the slow path. Here's the full picture, from the quick - operator to the Set-based version that scales.
Quick answer
For small lists, the minus operator does it: val aOnly = a - b. It removes every occurrence of anything in b from a, keeping order. For large lists, convert b to a Set first - val setB = b.toSet(); val aOnly = a.filterNot { it in setB } - to guarantee O(n + m) instead of a possible O(n * m). For symmetric difference, combine two subtracts: (a - b) + (b - a).
Need the same thing in another language?
See the full reference for Java, Swift, Python, SQL, and more.
The minus operator: quick and readable
val a = listOf("apple", "banana", "cherry", "banana")
val b = listOf("banana", "date")
val aOnly = a - b
println(aOnly) // [apple, cherry] - order preserved, all 'banana' occurrences removed a - b (equivalently a.minus(b)) reads naturally and preserves the order of a. It removes every occurrence of a matched item, not just the first, so a list with duplicates that also appear in b loses all of them.
The Set-based approach for large lists
val a = listOf("apple", "banana", "cherry")
val b = listOf("banana", "date")
val setB = b.toSet()
val aOnly = a.filterNot { it in setB }
println(aOnly) // [apple, cherry] Converting b to a Set once makes it in setB an O(1) hash lookup, so the whole filter is O(n + m). This is the version worth using once either list has more than a few hundred items - the plain minus operator's performance depends on the collection types involved, and staying explicit with a Set avoids relying on that.
subtract(): the function form
val a = setOf("apple", "banana", "cherry")
val b = setOf("banana", "date")
val aOnly = a.subtract(b)
println(aOnly) // [apple, cherry] subtract() is the named function behind the - operator when working with Sets. If your inputs are already Sets rather than Lists, this is the fastest form since it uses the set's hash-based lookup directly with no conversion step.
Symmetric difference
val a = listOf("apple", "banana", "cherry")
val b = listOf("banana", "date")
val symDiff = (a - b) + (b - a)
println(symDiff) // [apple, cherry, date] Kotlin has no built-in symmetric difference, but combining A-only and B-only with + gets there in one line. With Sets, the equivalent is (setA union setB) - (setA intersect setB).
Just need the answer, not the code? Paste both lists.
Open Compare 2 Lists →Frequently Asked Questions
What is the simplest way to find the difference between two lists in Kotlin?
minus operator: val aOnly = a - b (equivalent to a.subtract(b) as a set, or a.minus(b) as a function call). It returns every item in a that doesn't appear in b, removing all occurrences of matched items.Does the minus operator on a List preserve order and duplicates?
b contains an item, every occurrence of it is removed from a, not just one. If you need to remove only one occurrence per match, filter manually with a mutable count, or convert to a multiset-style structure.Is a - b slow for large lists in Kotlin?
List.minus(Collection) internally checks b.contains() for filtering behavior in some overloads, which is O(m) per item if b is a plain List, giving O(n * m) overall. Converting b to a Set first - val setB = b.toSet(); val aOnly = a.filterNot { it in setB } - guarantees O(1) lookups and O(n + m) total.How do I get the difference between two sets in Kotlin?
a and b are already Sets, a - b or a.subtract(b) is O(n) using the set's own hash-based lookup, no manual conversion needed. This is the fastest form when you control the input types.How do I get the symmetric difference of two lists in Kotlin?
val symDiff = (a - b) + (b - a), or with sets, (setA union setB) - (setA intersect setB).How do I compare two lists of data classes by a specific field in Kotlin?
equals() compares all properties), so a - b works directly if you want to compare whole objects. To compare by one field only, map to a set of that field first: val idsB = b.map { it.id }.toSet(); val aOnly = a.filterNot { it.id in idsB }.How do I do a case-insensitive list difference in Kotlin?
val setB = b.map { it.lowercase() }.toSet(); val aOnly = a.filterNot { it.lowercase() in setB }. This keeps the original casing of items in the result while matching case-insensitively.