コレクションの基本概念
Kotlinではデータを効率的に管理するための複数のコレクション型が提供されています。これらは主に以下の二つのカテゴリに分類されます:
- イミュータブルコレクション:要素の追加や削除ができない読み取り専用の構造です。
- ミュータブルコレクション:実行時に要素の変更が可能な動的なデータ構造です。
主要なコレクション型
- List:順序付きで重複を許容する要素の並び。
- Set:順序を持たず、重複しない一意の要素群。
- Map:キーと値のペアで構成される連想配列。
Listの操作
Listは挿入された順序を保持し、同じ値を持つ複数の要素を格納できます。
// 読み取り専用リストの生成
val fruits: List<String> = listOf("Orange", "Grape", "Mango")
// 変更可能なリストの作成と操作
val editableFruits: MutableList<String> = mutableListOf("Orange", "Grape")
editableFruits.add("Kiwi")
editableFruits.remove("Grape")
println(editableFruits) // 結果: [Orange, Kiwi]
Setの特性と利用法
Setは各要素が一意であることを保証し、要素の順序には依存しません。
// 固定セットの定義
val uniqueNumbers: Set<Int> = setOf(10, 20, 30, 40)
// 可変セットの操作
val dynamicSet: MutableSet<Int> = mutableSetOf(10, 20)
dynamicSet.add(30)
dynamicSet.add(20) // 重複要素は無視される
println(dynamicSet) // 出力: [10, 20, 30]
Mapによるキー・バリュー管理
Mapはユニークなキーに関連付けられた値を格納する構造です。
// 読み取り専用マップの初期化
val itemPrices: Map<String, Double> = mapOf("Laptop" to 999.99, "Mouse" to 25.0)
// 可変マップの更新処理
val priceCatalog: MutableMap<String, Double> = mutableMapOf("Laptop" to 999.99)
priceCatalog["Keyboard"] = 75.5
priceCatalog.remove("Laptop")
println(priceCatalog) // 表示: {Keyboard=75.5}
高度なコレクション処理
Kotlinの関数型プログラミング機能により、簡潔かつ表現力豊かなデータ操作が可能です。
代表的な高階関数
// map: 各要素を変換
val digits = listOf(2, 4, 6, 8)
val cubes = digits.map { it * it * it }
println(cubes) // 結果: [8, 64, 216, 512]
// filter: 条件に合う要素のみ抽出
val values = listOf(5, 10, 15, 20)
val multiplesOfTen = values.filter { it % 10 == 0 }
println(multiplesOfTen) // 出力: [10, 20]
// reduce: 単一の結果へ集約
val nums = listOf(1, 3, 5, 7)
val total = nums.reduce { sum, current -> sum + current }
println(total) // 値: 16
// fold: 初期値を指定して集約
val items = listOf(2, 3, 4)
val factorial = items.fold(1) { product, value -> product * value }
println(factorial) // 結果: 24
// sorted: 昇順ソート
val randomOrder = listOf(7, 2, 9, 1)
val ordered = randomOrder.sorted()
println(ordered) // 表示: [1, 2, 7, 9]
コレクション間の変換処理
// リストからセットへの変換
val sequence = listOf(1, 1, 2, 3)
val distinctElements = sequence.toSet()
val pairedMapping = sequence.associateBy { "Item$it" }
println(distinctElements) // 出力: [1, 2, 3]
println(pairedMapping) // 表示: {Item1=1, Item2=2, Item3=3}
// ネストされたリストの平坦化
val matrix = listOf(listOf(1, 2), listOf(3, 4), listOf(5))
val linear = matrix.flatten()
println(linear) // 結果: [1, 2, 3, 4, 5]
遅延評価によるパフォーマンス最適化
大量のデータを扱う際や複雑な変換チェーンが必要な場合は、Sequenceを使用することで計算の効率化が図れます。Sequenceでは中間操作は即時実行されず、最終的な走査時に評価されます。
// 数列生成と遅延フィルタリング
val infiniteStream = generateSequence(1) { it + 1 }
.asSequence()
.filter { it % 3 == 0 }
.map { it * it }
.take(5)
.toList()
println(infiniteStream) // 出力: 最初の5つの3の倍数の平方 [9, 36, 81, 144, 225]