Kotlin でコレクションを並び替える場合、sorted や sort といった関数を使います。
しかし、これらは似た名前でも動作が大きく異なり、データの扱い方を正しく理解しておかないと予期しない挙動につながることがあります。
ここでは、Kotlin の並び替え機能を体系的に整理しながら、実際の挙動を詳しく解説します。
sorted 系と sort 系の本質的な違い
Kotlin の並び替え関数は大きく次の 2 種類に分かれます。
sorted 系(新しい List を返す)
sorted()sortedBy { ... }sortedWith(...)sortedDescending()sortedByDescending { ... }
特徴:元のコレクションは変更されず、新しい並び順の List が生成される。
レシーバは Iterable<T> なので、List でも MutableList でも利用できます。
sort 系(MutableList 自体を変更する)
sort()sortBy { ... }sortWith(...)sortDescending()sortByDescending { ... }
特徴:MutableList<T> の内容を直接並び替える。
返り値は Unit で、インプレース変更が行われます。
sorted 系の基本動作
不変のまま新しい結果が必要な場合に便利です。
val numbers = listOf(3, 1, 4, 2)
val sortedNumbers = numbers.sorted()
println(sortedNumbers) // [1, 2, 3, 4]
println(numbers) // [3, 1, 4, 2]
このように、元のリストは保持されます。
sort 系の基本動作
MutableList の内容を直接変更します。
val numbers = mutableListOf(3, 1, 4, 2)
numbers.sort()
println(numbers) // [1, 2, 3, 4]
返り値は Unit で、並び替え結果はリスト自身に反映されます。
昇順・降順での並び替え
昇順
val sorted = list.sorted()
mutableList.sort()
降順
val sorted = list.sortedDescending()
mutableList.sortDescending()
特定の条件でソートする
1 つのプロパティを基準に並び替える(sortedBy / sortBy)
data class User(val name: String, val age: Int)
val users = listOf(
User("Taro", 30),
User("Hanako", 20),
User("Ken", 25)
)
val sorted = users.sortedBy { it.age }
結果は年齢順に並びます。
降順でプロパティソート
val sorted = users.sortedByDescending { it.age }
複数条件でソートする(sortedWith / sortWith)
Comparator を組み合わせて複数の基準を持つ並び替えができます。
val sorted = users.sortedWith(
compareBy<User> { it.age }.thenBy { it.name }
)
年齢の昇順 → 名前の昇順という優先度で並び替えられます。
降順を混ぜることも可能です。
val sorted = users.sortedWith(
compareByDescending<User> { it.age }.thenBy { it.name }
)
null を含むデータのソート
null を後ろに寄せる例
val list: List<String?> = listOf("b", null, "a")
val sorted = list.sortedWith(
nullsLast(naturalOrder<String>())
)
println(sorted) // [a, b, null]
List に sort() が使えない理由
sort() は MutableList<T> のみに定義された拡張関数であり、List<T> にはそもそもインプレース変更の概念がないためです。
val list = listOf(3, 2, 1)
list.sort() // コンパイルエラー
必要な場合は MutableList へ変換します。
val mutable = list.toMutableList()
mutable.sort()
Kotlin/JVM のソートアルゴリズム
Kotlin 自身がソートアルゴリズムを独自実装しているわけではなく、JVM 上では Java 標準ライブラリのソート処理に委譲しています。
- Java の List.sort / Arrays.sort が採用される
- TimSort ベースの安定ソート
- 計算量は O(n log n)
このため、大規模データでも安定した性能が得られます。
よく使う並び替えパターンまとめ
| 目的 | 使用例 |
|---|---|
| 単純に昇順 | list.sorted() |
| 単純に降順 | list.sortedDescending() |
| 特定プロパティで昇順 | list.sortedBy { it.age } |
| 特定プロパティで降順 | list.sortedByDescending { it.age } |
| 複数条件 | sortedWith(compareBy { ... }.thenBy { ... }) |
| 元データを変更したい | mutableList.sort() |
まとめ
Kotlin の sort は、sorted 系(新しい List を返す) とsort 系(MutableList 自体を変更する) を理解すると使いこなしやすくなります。
特定のプロパティを基準にしたソート、複数条件でのソート、null を含むデータの扱いなど、用途に応じて柔軟に活用できます。
以上、Kotlinのsortについてでした。
最後までお読みいただき、ありがとうございました。



