セット — setOf() / mutableSetOf()
| 対応: | Kotlin 1.0(2016) |
|---|
Kotlinの『setOf()』で不変セット、『mutableSetOf()』で可変セットを作成します。セットは重複なしの集合で、『union()』(和)、『intersect()』(積)、『subtract()』(差)などの集合演算が使えます。
構文
// 不変セットの作成(重複は自動で除去されます)
val members = setOf("item_a", "item_b", "item_a", "item_c")
// {item_a, item_b, item_c}(重複1件除去)
// 可変セットの作成
val tags = mutableSetOf("kotlin", "jvm")
tags.add("android")
tags.remove("jvm")
// 集合演算
val a = setOf(1, 2, 3, 4)
val b = setOf(3, 4, 5, 6)
val union = a union b // {1, 2, 3, 4, 5, 6}
val intersect = a intersect b // {3, 4}
val subtract = a subtract b // {1, 2}
メソッド一覧
| メソッド | 概要 |
|---|---|
| setOf(要素...) | 不変セットを作成します(重複は自動除去)。 |
| mutableSetOf(要素...) | 可変セットを作成します。 |
| LinkedHashSet<T>() | 挿入順を保持するセットです。 |
| sortedSetOf(要素...) | 自然順でソートされたセットです。 |
| セット.contains(要素) | 要素が含まれるか確認します(in 演算子でも可)。 |
| セット.union(other) | 和集合(A ∪ B)を返します。 |
| セット.intersect(other) | 積集合(A ∩ B)を返します。 |
| セット.subtract(other) | 差集合(A − B)を返します。 |
| MutableSet.add(要素) | 要素を追加します(重複は無視)。 |
| MutableSet.remove(要素) | 要素を削除します。 |
| リスト.toSet() | リストをセットに変換します(重複除去に使います)。 |
| リスト.distinct() | 重複を除いたリストを返します(順序保持)。 |
サンプルコード
sample_set_create.kt
fun main() {
// 基本のセット(重複自動除去)
val members = setOf("item_a", "item_b", "item_a", "item_c", "item_b")
println("members: $members") // 重複除去済み
println("サイズ: ${members.size}")
// 存在確認
println("item_bあり: ${"item_b" in members}") // true
println("item_eあり: ${"item_e" in members}") // false
println()
// 可変セット
val langs = mutableSetOf("Kotlin", "Java", "Python")
langs.add("Swift")
langs.add("Kotlin") // 重複 — 無視されます
langs.remove("Java")
println("言語: $langs")
println()
// 集合演算
val set1 = setOf(1, 2, 3, 4, 5)
val set2 = setOf(3, 4, 5, 6, 7)
println("和集合: ${set1 union set2}") // {1,2,3,4,5,6,7}
println("積集合: ${set1 intersect set2}") // {3,4,5}
println("差集合: ${set1 subtract set2}") // {1,2}
println("逆差集合: ${set2 subtract set1}") // {6,7}
println()
// リストの重複除去
val items = listOf("item_a", "item_b", "item_a", "item_c", "item_b", "item_d")
println("元リスト(${items.size}件): $items")
val unique = items.toSet()
println("重複除去(${unique.size}件): $unique")
// distinct() — 順序を保持して重複除去します
val distinctList = items.distinct()
println("distinct(${distinctList.size}件): $distinctList")
println()
// 実用例: 共通の要素を見つけます
val teamA = setOf("item_b", "item_c", "item_d", "item_f")
val teamB = setOf("item_a", "item_c", "item_e", "item_f")
val common = teamA intersect teamB
println("共通要素: $common")
}
set_create.kt
kotlinc set_create.kt -include-runtime -d set_create.jar java -jar set_create.jar members: [item_a, item_b, item_c] サイズ: 3 item_bあり: true item_eあり: false 言語: [Kotlin, Python, Swift] 和集合: [1, 2, 3, 4, 5, 6, 7] 積集合: [3, 4, 5] 差集合: [1, 2] 逆差集合: [6, 7] 元リスト(6件): [item_a, item_b, item_a, item_c, item_b, item_d] 重複除去(4件): [item_a, item_b, item_c, item_d] distinct(4件): [item_a, item_b, item_c, item_d] 共通要素: [item_c, item_f]
よくあるミス
sample_set_create_mistakes.kt
fun main() {
// setOf() は不変なので add/remove しようとする
val items = setOf("item_b", "item_a", "item_c")
// items.add("item_d") // コンパイルエラー: unresolved reference: add
// items.remove("item_a") // コンパイルエラー
// 変更するときは mutableSetOf() を使う
// subtract の演算順序を間違える
val setA = setOf("item_b", "item_a", "item_c")
val setB = setOf("item_a", "item_d")
val wrong = setB subtract setA // B から A を引く(A から B ではない)
println("間違い: $wrong") // [item_d](item_bとitem_cが含まれない)
// A にいて B にいない要素は A subtract B で取得する
println("正しい: ${setA subtract setB}") // [item_b, item_c]
// セットの順序に依存する処理を書く
// HashSet は順序が保証されない(setOf は LinkedHashSet なので挿入順だが実装依存)
val hashSet = hashSetOf("item_b", "item_a", "item_c")
println(hashSet) // 順序は実行ごとに変わる可能性がある
// 順序が必要なら sortedSetOf(昇順)を使う
val sorted = sortedSetOf("item_b", "item_a", "item_c")
println(sorted) // 文字コード順でソートされる
}
コンパイルして実行すると次のようになります。
kotlinc sample_set_create_mistakes.kt -include-runtime -d sample_set_create_mistakes.jar java -jar sample_set_create_mistakes.jar 間違い: [item_d] 正しい: [item_b, item_c] [item_a, item_b, item_c] [item_a, item_b, item_c]
概要
セットは「重複なしで存在確認が速い」コレクションです。要素の存在確認(『contains()』)はリストがO(n)なのに対し、セット(HashSet)はO(1)で高速です。大量データで特定の要素が含まれるか頻繁に確認する場合はセットが適しています。
Kotlinの『setOf()』はデフォルトで挿入順を保持する『LinkedHashSet』を使います。挿入順が不要で純粋なHashSetを使いたい場合は『hashSetOf()』を使います。
マップの操作はマップ — mapOf() / mutableMapOf()を、リストの基本はリスト — 生成 / listOf() / mutableListOf()を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。