Question
How can I remove duplicate values from an Array<String?> in Kotlin?
For example, given an array of nullable strings, I want to create a result that keeps only one copy of each value, including handling null correctly when it appears.
Short Answer
By the end of this page, you will understand how to remove duplicate values from a Kotlin array, especially an Array<String?>. You will learn the most common Kotlin approaches such as distinct(), converting to a Set, and when to choose each option. You will also see how null values behave and how order is affected.
Concept
In Kotlin, removing duplicates means keeping only unique values from a collection.
For an Array<String?>, duplicates can include:
- repeated strings like
"apple" - repeated
nullvalues
Kotlin provides collection functions that make this simple. The most beginner-friendly option is distinct().
val items = arrayOf("apple", "banana", "apple", null, null)
val unique = items.distinct()
println(unique) // [apple, banana, null]
Why this works
distinct() returns a new list containing only the first occurrence of each value. If the same value appears again later, Kotlin skips it.
This matters because duplicate removal is common in real programs:
- cleaning user input
- preparing API data
- filtering repeated tags or categories
- avoiding repeated processing
Important detail: arrays vs lists
In Kotlin, Array is not the same as List.
Array<String?>is a fixed-size arraydistinct()returns aList<String?>
So if you want the final result to still be an array, convert it back:
val uniqueArray = items.distinct().toTypedArray()
How null is handled
Kotlin treats null like any other value for duplicate checking. That means:
- one
nullis kept - repeated
nullvalues are removed
Example:
val items = arrayOf("a", null, "a", null)
val unique = items.distinct()
println(unique) // [a, null]
Order preservation
distinct() preserves the original order of first appearances.
val items = arrayOf("b", "a", "b", "c")
val unique = items.distinct()
println(unique) // [b, a, c]
This is often useful because you usually want unique values without scrambling the original order.
Mental Model
Think of duplicate removal like checking people into an event.
- You have a list of names arriving in order.
- A staff member keeps a record of who has already entered.
- If a name appears for the first time, it is allowed in.
- If the same name appears again, it is ignored.
nullis like a guest with no name tag: the first one is still recorded, but repeated unnamed entries are ignored.
So Kotlin's duplicate-removal process is basically:
- read each item from left to right
- remember what has already been seen
- keep only the first appearance of each value
Syntax and Examples
The most common ways to remove duplicates from an Array<String?> in Kotlin are below.
1. Use distinct()
val items = arrayOf("apple", "banana", "apple", null, "banana", null)
val unique = items.distinct()
println(unique) // [apple, banana, null]
distinct()returns aList<String?>- it keeps the first occurrence of each value
- it preserves order
2. Convert back to an array
If you need an array as the result:
val items = arrayOf("apple", "banana", "apple", null)
val uniqueArray = items.distinct().toTypedArray()
println(uniqueArray.contentToString()) // [apple, banana, null]
3. Use toSet()
val items = arrayOf("apple", "banana", "apple", null)
val uniqueSet = items.toSet()
println(uniqueSet) // [apple, banana, null]
This also removes duplicates, but the result type is a Set<String?>, not an array or list.
4. Remove duplicates and remove nulls
If you want only unique non-null strings:
val items = arrayOf("apple", null, "apple", "banana", null)
val uniqueNonNull = items.filterNotNull().distinct()
println(uniqueNonNull) // [apple, banana]
Beginner-friendly example
fun main() {
val names: Array<String?> = arrayOf("Ali", "Mina", "Ali", null, "Sara", null)
val uniqueNames = names.distinct()
println(uniqueNames)
}
What this prints
[Ali, Mina, null, Sara]
Why
Aliappears twice, so only the first one is keptnullappears twice, so only onenullis kept- order stays the same as the original array
Step by Step Execution
Consider this example:
val items = arrayOf("cat", null, "dog", "cat", null, "bird")
val unique = items.distinct()
println(unique)
Let's trace it.
Initial array
["cat", null, "dog", "cat", null, "bird"]
Step 1: read "cat"
- not seen before
- keep it
Current result:
["cat"]
Step 2: read null
- not seen before
- keep it
Current result:
["cat", null]
Step 3: read "dog"
- not seen before
- keep it
Current result:
["cat", null, "dog"]
Step 4: read "cat" again
- already seen
- skip it
Current result stays:
["cat", null, "dog"]
Step 5: read null again
- already seen
- skip it
Current result stays:
["cat", null, "dog"]
Step 6: read "bird"
- not seen before
- keep it
Final result:
["cat", null, "dog", "bird"]
Printed output
[cat, null, dog, bird]
Real World Use Cases
Removing duplicates from arrays and collections is common in many Kotlin applications.
User input cleanup
A form may collect repeated tags or categories.
val tags = arrayOf("kotlin", "android", "kotlin", null)
val uniqueTags = tags.distinct()
API response cleanup
Sometimes API data contains repeated values.
val cities = arrayOf("Paris", "Tokyo", "Paris")
val uniqueCities = cities.distinct()
Search history
You may want to show each search term only once.
val searches = arrayOf("phone", "laptop", "phone")
val uniqueSearches = searches.distinct()
Data import scripts
CSV or database imports often need duplicate filtering before saving.
val emails = arrayOf("a@example.com", "b@example.com", "a@example.com")
val uniqueEmails = emails.distinct()
UI dropdown options
A dropdown should not show the same option multiple times.
val categories = arrayOf("Books", "Games", "Books")
val uniqueCategories = categories.distinct()
Real Codebase Usage
In real Kotlin codebases, developers usually choose a duplicate-removal approach based on the result type they need.
Common pattern: distinct() for readable code
val uniqueNames = names.distinct()
This is the most readable and idiomatic choice when you want a list.
When an array is still required
val uniqueNamesArray = names.distinct().toTypedArray()
This is common when calling older APIs or code that specifically expects Array<String?>.
Validation before duplicate removal
Developers often clean data first, then deduplicate it.
val cleaned = names
.filterNotNull()
.map { it.trim() }
.filter { it.isNotEmpty() }
.distinct()
This pattern is common when processing form fields or imported text.
Early data normalization
In real projects, duplicate removal is often part of a pipeline:
val result = rawValues
.filterNotNull()
.map { it.lowercase() }
.distinct()
This avoids treating "Kotlin" and "kotlin" as different if the business rule says they should match.
Set-based usage
If the codebase needs fast membership checks later, developers may keep the data as a set.
val allowedNames = names.toSet()
if ("Ali" in allowedNames) {
println("Found")
}
This is useful when uniqueness is more important than array/list behavior.
Common Mistakes
Here are common beginner mistakes when removing duplicates in Kotlin.
Mistake 1: Expecting distinct() to return an array
val items: Array<String?> = arrayOf("a", "a", null)
val unique: Array<String?> = items.distinct() // Error
Why it fails
distinct() returns a List<String?>, not an Array<String?>.
Fix
val unique: Array<String?> = items.distinct().toTypedArray()
Mistake 2: Forgetting that null is kept once
Some beginners expect all null values to disappear automatically.
val items = arrayOf("a", null, "a", null)
println(items.distinct()) // [a, null]
Fix
If you want to remove null completely:
val uniqueNonNull = items.filterNotNull().distinct()
Mistake 3: Using toSet() without noticing the type change
val items = arrayOf("a", "b", "a")
val unique = items.toSet()
This works, but unique is a Set<String?>, not a list or array.
Fix
Choose the method based on the result type you need.
Mistake 4: Assuming case differences are duplicates
val items = arrayOf("Kotlin", "kotlin")
println(items.distinct()) // [Kotlin, kotlin]
These are different strings.
Fix
Normalize first if needed:
val unique = items.map { it?.lowercase() }.distinct()
Mistake 5: Assuming duplicates are removed in place
val items = arrayOf("a", "a", "b")
items.distinct()
println(items.contentToString()) // [a, a, b]
Why
distinct() returns a new collection. It does not change the original array.
Fix
Store the result:
val unique = items.distinct()
Comparisons
Here is how the main options compare.
| Approach | Returns | Preserves first-seen order | Keeps one null | Best for |
|---|---|---|---|---|
distinct() | List<String?> | Yes | Yes | Idiomatic duplicate removal |
distinct().toTypedArray() | Array<String?> | Yes | Yes | When you still need an array |
toSet() | Set<String?> | Typically yes for Kotlin's default set creation, but use it mainly for uniqueness rather than sequence behavior | Yes | Unique membership checks |
filterNotNull().distinct() | List<String> | Yes | No | Unique values with no nulls |
distinct() vs toSet()
val items = arrayOf("a", "b", "a", null)
val asList = items.distinct()
val asSet = items.toSet()
- Use
distinct()when you want a clear, ordered result for display or further list processing. - Use
toSet()when you want uniqueness as a property and may perform membership checks.
Array vs List in Kotlin
| Type | Size | Common use |
|---|---|---|
Array<String?> | Fixed size | Interop, specific APIs, indexed storage |
List<String?> | Read-only view of values | Most Kotlin collection operations |
In Kotlin, many helpful operations return lists, so converting from arrays to lists and back is normal.
Cheat Sheet
// Original array
val items: Array<String?> = arrayOf("a", "b", "a", null, null)
// Remove duplicates -> List<String?>
val uniqueList = items.distinct()
// Remove duplicates -> Array<String?>
val uniqueArray = items.distinct().toTypedArray()
// Remove duplicates -> Set<String?>
val uniqueSet = items.toSet()
// Remove nulls first, then duplicates -> List<String>
val uniqueNonNull = items.filterNotNull().distinct()
// Normalize case, then remove duplicates
val uniqueLower = items.map { it?.lowercase() }.distinct()
Quick rules
distinct()returns a newList- it keeps the first occurrence of each value
- it preserves order
- repeated
nullvalues become a singlenull - use
toTypedArray()if you need an array again - use
filterNotNull()ifnullshould be removed entirely
Common patterns
items.distinct()
items.distinct().toTypedArray()
items.filterNotNull().distinct()
items.map { it?.trim() }.distinct()
Watch out for
"A"and"a"are different unless normalized- original array is not modified
toSet()changes the collection type
FAQ
How do I remove duplicates from an array in Kotlin?
Use distinct().
val unique = items.distinct()
If you need an array result, use:
val uniqueArray = items.distinct().toTypedArray()
Does Kotlin distinct() work with null values?
Yes. It treats null as a normal value and keeps only one null if multiple are present.
Does distinct() preserve order in Kotlin?
Yes. It keeps values in the order of their first appearance.
What is the difference between distinct() and toSet() in Kotlin?
distinct() returns a List, while toSet() returns a Set. Both remove duplicates, but they produce different collection types.
How do I remove duplicates and also remove null values?
Use filterNotNull() before distinct().
val result = items.filterNotNull().distinct()
Can I remove duplicates directly inside the original array?
Not in place with distinct(). Arrays have fixed size, so you usually create a new list or a new array.
Why does distinct() not return an array?
Because Kotlin's collection functions commonly return lists for flexibility and consistency. Convert back with toTypedArray() if needed.
Mini Project
Description
Create a small Kotlin program that cleans a list of imported usernames. The imported data may contain repeated names and repeated null values. Your program should produce a clean result with unique values while preserving the original order. This demonstrates real-world collection cleanup on nullable string arrays.
Goal
Build a Kotlin program that removes duplicate values from an Array<String?> and prints both the original and cleaned results.
Requirements
- Create an
Array<String?>with duplicate strings and duplicatenullvalues. - Print the original array.
- Remove duplicates while preserving order.
- Convert the result back to an array.
- Print the cleaned array.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Add a Maven Repository URL in Gradle Kotlin DSL (build.gradle.kts)
Learn how to add Maven Central and a custom Maven repository URL in Gradle Kotlin DSL using build.gradle.kts syntax.
Allow HTTP and HTTPS in Android 9 Pie with Network Security Configuration
Learn how Android 9 Pie handles cleartext HTTP traffic and how to allow HTTP and HTTPS safely using network security config.