MENU

【Kotlin】レッスン4-06:コレクション×ジェネリクスを学ぼう|型安全なコードの基本を習得

tggaa478@yahoo.co.jp

一つ前のページではコレクション操作について学習しました。

今回は コレクションとジェネリクスの組み合わせ について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数編
Lesson4:コレクション編

 ・Lesson4-1:配列を理解しよう
 ・Lesson4-2:Listを理解しよう
 ・Lesson4-3:Setを理解しよう
 ・Lesson4-4:Mapを理解しよう
 ・Lesson4-5:コレクションを使いこなそう
 ・Lesson4-6:コレクションとジェネリクスを組み合わせよう ◁今回はココ
 ・確認問題4-☆1:ナインゲームを作ろう
 ・確認問題4-☆2:アラビア数字をローマ数字に変換しよう
 ・確認問題4-☆3:宝探しゲームを作ろう
Lesson5:オブジェクト指向編

<<前のページ

学習記事一覧

次のページ>>

コレクション×ジェネリクスの基本とは?|Kotlinで型を制御する方法

Kotlinではコレクション(List、Set、Mapなど)がプログラムの中核を担いますが、型安全性を保ちながらこれらを効率よく扱うためにはジェネリクスの理解が重要です。

本記事ではコレクションとジェネリクスを組み合わせて使う方法を解説します。

ジェネリクスの基本|Kotlinで型安全性を保つ仕組み

ジェネリクス(Generics)とは、コードの再利用性や型安全性を高めるために導入された仕組みです。

以下は簡単な例です:

// 型を指定しないリスト
val list = listOf(1, "string", true) // あらゆる型が混在可能

// ジェネリクスを使った型安全なリスト
val intList: List<Int> = listOf(1, 2, 3) // Int型のみに制限

ジェネリクスを利用することで、開発者は意図しない型のデータが混入することを防ぎ、実行時エラーを回避できます。

Kotlinでは関数やクラスに <T> を指定することでジェネリック型を定義できます。

あわせて読みたい
【Kotlin】レッスン3-06:ジェネリクスの基礎を理解しよう|型に依存しない関数を作成
【Kotlin】レッスン3-06:ジェネリクスの基礎を理解しよう|型に依存しない関数を作成

ジェネリクス×コレクションの実践例|型指定で安全なListやMapを

コレクションとジェネリクスを組み合わせることで、特定の型だけを受け入れる安全なコレクションを作成できます。

これにより次のような利点が得られます:

  1. 型安全性の向上:不正な型の要素追加がコンパイル時に防止されます。
  2. コードの可読性向上:型情報が明示されることで、コードの意図が明確になります。

例えば次のようなコードを考えてみましょう:

val stringList: List<String> = listOf("Kotlin", "Java", "Python")
// stringListにInt型を追加しようとするとエラーになる

Kotlinでのジェネリクス構文|リスト・マップへの応用例

Kotlinのコレクションにジェネリクスを適用する基本構文を以下に示します:

val numbers: List<Int> = listOf(1, 2, 3)
val strings: List<String> = listOf("A", "B", "C")
val uniqueNumbers: Set<Int> = setOf(1, 2, 3, 1) // 重複要素は無視
val userMap: Map<Int, String> = mapOf(1 to "Alice", 2 to "Bob")

開発で使えるジェネリクス活用例|filterやmap処理も型安全に

ジェネリクスはコレクション操作で特に便利です。以下は具体例です:

検索やフィルタリング

val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // 出力: [ 2, 4]

Mapでのキーと値

val userMap: Map<Int, String> = mapOf(1 to "Alice", 2 to "Bob")
val userName = userMap[ 1] // "Alice"を取得

これらの例では、ジェネリクスを活用することで操作の対象が期待通りの型であることを保証しています。

コレクションとジェネリクスまとめ|今後の活用のために整理しよう

コレクションとジェネリクスを組み合わせることで、Kotlinのコードはより安全で読みやすくなります。

型の安全性を高めるジェネリクスはKotlinプログラミングにおいて重要な役割を果たしており、コレクションの操作と組み合わせることで、効率的かつエラーの少ないコードが実現します。

ぜひこの仕組みを活用してみてください!

練習問題|型安全なリスト・マップを作成して扱おう

コレクションとジェネリクスを活用して、型安全なリストやマップを作成するプログラムを作りましょう。

リストから条件に合う要素を抽出したり、マップからキーに対応する値を取得する操作を学びます。

また重複を許さない集合(Set)を使った例も含まれています。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • 型安全なリスト numbers を作成し、値として 10, 20, 30, 40, 50 を格納すること。
  • 型安全なマップ userMap を作成し、キーとして 1, 2, 3、値としてそれぞれ "佐藤""田中""鈴木" を格納すること。
  • numbers の中から偶数のみを抽出してリストに格納し、その内容を表示すること。
  • userMap からキー 2 に対応する値を取得し、その内容を表示すること。
  • 型安全な集合 uniqueNumbers を作成し、値として 1, 2, 2, 3, 4, 4 を格納して表示すること。

ただし、以下のような実行結果となること。

数値リスト: [10, 20, 30, 40, 50]
ユーザー一覧: {1=佐藤, 2=田中, 3=鈴木}
偶数リスト: [10, 20, 30, 40, 50]
キー2のユーザー: 田中
ユニークな数値セット: [ 1, 2, 3, 4]

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:main関数の定義
  □ Listを用いた型安全なリストnumbersを定義し、初期化
  □ printlnでリストの内容を出力
  □ Mapを用いた型安全なマップuserMapを定義し、初期化
  □ printlnでマップの内容を出力
  □ Listのfilter関数を用いて偶数リストevenNumbersを作成
  □ printlnで偶数リストを出力
  □ Mapの検索機能を用いてキー2に対応する値を取得し、変数userNameに代入
  □ if文でuserNameがnullでないかを判定
  □ □ 真の場合、printlnで対応するユーザーを出力
  □ □ else文
  □ □ □ 該当ユーザーがいない場合にprintlnでメッセージを出力
  □ Setを用いた型安全な集合uniqueNumbersを定義し、初期化
  □ printlnでユニークな数値セットを出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

// メイン関数:プログラムのエントリポイント
fun main() {
    // Listのジェネリクス例: 型安全なリストを作成
    /*【穴埋め問題1】
    ここでListを用いて型安全なリストnumbersを定義し、初期化するコードを書いてください。
    */

    println("数値リスト: $numbers")

    // Mapのジェネリクス例: キーと値の型を指定したマップ
    /*【穴埋め問題2】
    ここでMapを用いて型安全なマップuserMapを定義し、初期化するコードを書いてください。
    */

    println("ユーザー一覧: $userMap")

    // フィルタリングの例
    /*【穴埋め問題3】
    ここでnumbersのfilter関数を用いて、偶数リストevenNumbersを作成するコードを書いてください。
    */

    println("偶数リスト: $evenNumbers")

    // Mapの検索例
    /*【穴埋め問題4】
    ここでuserMapからキー2に対応する値を取得し、変数userNameに代入するコードを書いてください。
    */

    if (userName != null) {
        println("キー2のユーザー: $userName")
    } else {
        println("該当するユーザーが見つかりません")
    }

    // Setのジェネリクス例: 重複を許さない型安全な集合
    /*【穴埋め問題5】
    ここでSetを用いて型安全な集合uniqueNumbersを定義し、初期化するコードを書いてください。
    */

    println("ユニークな数値セット: $uniqueNumbers")
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

練習問題の解答と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
// メイン関数:プログラムのエントリポイント
fun main() {
    // Listのジェネリクス例: 型安全なリストを作成
    val numbers: List<Int> = listOf(10, 20, 30, 40, 50) // Int型のリスト
    println("数値リスト: $numbers")

    // Mapのジェネリクス例: キーと値の型を指定したマップ
    val userMap: Map<Int, String> = mapOf(1 to "佐藤", 2 to "田中", 3 to "鈴木") // Intがキー、Stringが値
    println("ユーザー一覧: $userMap")

    // フィルタリングの例
    val evenNumbers = numbers.filter { it % 2 == 0 } // 偶数のみを抽出
    println("偶数リスト: $evenNumbers")

    // Mapの検索例
    val userName = userMap[ 2] // キー2の値を取得
    if (userName != null) {
        println("キー2のユーザー: $userName")
    } else {
        println("該当するユーザーが見つかりません")
    }

    // Setのジェネリクス例: 重複を許さない型安全な集合
    val uniqueNumbers: Set<Int> = setOf(1, 2, 2, 3, 4, 4) // 重複要素は自動的に削除
    println("ユニークな数値セット: $uniqueNumbers")
}
Q
正解コードの解説

コードをブロックごとに分割して解説します解説します。

メイン関数の開始

fun main() {
    // メイン関数:プログラムのエントリーポイント
}

fun main() はプログラムの開始点です。Kotlinプログラムはここから実行されます。

Listのジェネリクス例

val numbers: List<Int> = listOf(10, 20, 30, 40, 50)
println("数値リスト: $numbers")
  • List<Int> は整数型のリストを作成しています。ジェネリクス <Int> によりリスト内に整数以外の値を含めることができなくなり、型安全性を確保できます。
  • listOf は不変(変更不可)なリストを作成するための関数です。

Mapのジェネリクス例

val userMap: Map<Int, String> = mapOf(1 to "佐藤", 2 to "田中", 3 to "鈴木")
println("ユーザー一覧: $userMap")
  • Map<Int, String> はキーが整数型、値が文字列型であるマップを作成します。
  • mapOf はキーと値のペアを指定してマップを作成する関数です。ここでは、1 to "佐藤" のように to 演算子でペアを作ります。

リストから条件に合う値を抽出

val evenNumbers = numbers.filter { it % 2 == 0 }
println("偶数リスト: $evenNumbers")
  • filter 関数はリストの各要素を条件(ラムダ式)で評価し、条件を満たす要素のみを抽出します。
  • { it % 2 == 0 } はリスト内の偶数を抽出する条件です。

Mapの値を検索

val userName = userMap[ 2]
if (userName != null) {
    println("キー2のユーザー: $userName")
} else {
    println("該当するユーザーが見つかりません")
}
  • userMap[ 2] はキー 2 に対応する値(ここでは "田中")を取得します。
  • 値が存在しない場合は null が返されるため、if 文で確認しています。

Setのジェネリクス例

val uniqueNumbers: Set<Int> = setOf(1, 2, 2, 3, 4, 4)
println("ユニークな数値セット: $uniqueNumbers")
  • Set<Int> は重複を許さない集合です。ジェネリクスにより整数型だけを許可しています。
  • setOf は集合を作成する関数で、重複した値(ここでは 24)は自動的に除外されます。

まとめ

このプログラムではKotlinにおける「コレクション」と「ジェネリクス」の組み合わせを学びました。

これにより型安全なリスト、マップ、セットを操作し、データの整合性を保ちながら効率的に処理する方法を体験できました。

コレクション操作とジェネリクスをマスターすることでエラーを減らし、より安全で読みやすいコードを書くスキルが向上します。

もっと分かりやすいサイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいKotlin学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました