カテゴリー
Kotlin言語

ゼロから始めるAndroidアプリ(Kotlin編)Unit2 – 2 第1~2回 前半:Kotlinでリストを使う

Android Developers > スタートガイド > Kotlin と Android をゼロから学ぶ > Unit2 – レイアウトUnit2-2 第1回, 第2回 前半 の内容をまとめたものです(翻訳ではありません)


Unit2 – 2 の内容

  • Unit2 – 2 では、Android の UI部品(View)の RecyclerView をつかってスクロールリスト(scrollable list)を作ります
  • ひとまとめのデータを扱うのに便利な「リスト(list)」の使い方も説明します

Unit2 – 2 第1回~第2回 前半

第1回~第2回 前半 の内容は以下の通りです

  • 第1回は動画(英語)での紹介なので観なくても大丈夫です
  • Kotlinでのリスト(list)の作り方、使い方
  • List 型と MutableList 型の違い、それぞれの使い方
  • リストの項目(item)をループ処理で取り出して、それぞれの項目でなんらかの動作を実行させてみます

具体的にはつぎのようなレッスンです

  • Kotlinでリストを作ったりリストを操作してみます
  • Kotlinプログラムは Kotlin Playground にアクセスしてWebブラウザから実行できます

リストについて

Kotlinのリストは二種類あるんです

  • Int, Double, Boolean, String などの型は、基本的に型の決まったひとつの変数にひとつの値が代入されます
  • リストではひとつの変数に複数の値が保存できます
    • リストは一定の規則で項目(item)をまとめたものです
    • Listに含まれるひとつひとつの項目を要素(element)と言います
  • Kotlinには二種類のリストがあります
    • List 型・・・読み出し専用(Read-only)のリスト。一度生成すると変更できません
    • MutableList 型・・・変更可能(Mutable)なリスト。生成後に変更可能。要素(element)の追加、削除、変更が可能です
  • List 型や MutableList 型を使うときには、中に入れるデータの型を一緒に指定します
    • Int型のリストは List<Int>
    • 文字列型のリストは List<String>
    • Car というクラスを作って、そのインスタンスをリストにするときは List<Car> とします

List(変更不可)を使ってみる

List 型はあとから変更できないんです

List を使ったサンプルプログラムです

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6)
    println("List: $numbers")
    println("Size: ${numbers.size}")

    // Access elements of the list
    println("First element: ${numbers[0]}")
    println("Second element: ${numbers[1]}")
    println("Last index: ${numbers.size - 1}")
    println("Last element: ${numbers[numbers.size - 1]}")
    println("First: ${numbers.first()}")
    println("Last: ${numbers.last()}")

    // Use the contains() method
    println("Contains 4? ${numbers.contains(4)}")
    println("Contains 7? ${numbers.contains(7)}")
}

Kotlin でList型の変数を作るには listOf()(Kotlin標準ライブラリに含まれている)を使って次のようにします

val numbers: List<Int> = listOf(1, 2, 3, 4, 5, 6)

ただし、初期化に使う値からKotlinは型を推測できるので省略しても大丈夫。次のように書けます

val numbers = listOf(1, 2, 3, 4, 5, 6)

List型の変数も println() で直接表示できます

println("List: $numbers")

これは println("List: " + numbers) と書くのと同じです

size プロパティは List の要素数を保持しています。こんな風にリストの要素数を表示させることも可能です

println("Size: ${numbers.size}")

List の要素(element)にアクセスしてみる

添え字(index)は 0 からはじまります

  • Listのそれぞれの要素にアクセスするにはindex(添え字)を使います
  • index(添え字)は List の要素(elsement)に自動的に付けられます。0から順につけられた整数です

List 型の変数 numbers の最初の要素

  • numbers[0]
  • numbers.get(0)
  • numbers.first()
println("First element: ${numbers[0]}")
println("First element: ${numbers.get(0)}")
println("First element: ${numbers.first()}")

List 型の変数 numbers の最後の要素(要素が6個ある場合)

  • numbers[5]
  • numbers.get(5)
  • numbers[numbers.size -1]
  • numbers.last()
println("Last element: ${numbers[5]}")
println("Last element: ${numbers.get(5)}")
println("Last element: ${numbers[numbers.size - 1]}")
println("Last element: ${numbers.last()}")

List 型変数 numbers に、指定した要素があるかどうか判定する

  • numbers.contains(調べたい値)・・・結果は true/false で返される
println("Contains 4? ${numbers.contains(4)}")

List(変更不可)に適用するとリストを返す操作

  • reversed()・・・要素を逆順に並び替えたリストを返す
  • sorted()・・・要素を昇順に並び替えたリストを返す

元のリストは変化しないんです

fun main() {
    val colors = listOf("green", "orange", "blue")

    println("List: $colors")
    println("Reversed list: ${colors.reversed()}")
    println("Sorted list: ${colors.sorted()}")
}

MutableList について

MutableList 型はあとから変更できちゃいます

  • ミュータブルリストは後から変更が可能なリストです
  • 項目の add, remove, change などが可能です
  • List(変更不可)でできることはすべて出来ます
  • ミュータブルリストは MutableList 型として宣言し、mutableListOf() で作成できます

MutableList を使ったKotlinプログラム

MutableList を使ったサンプルプログラムです

fun main() {
    val entrees = mutableListOf<String>()
    println("Entrees: $entrees")

    // Add individual items using add()
    println("Add noodles: ${entrees.add("noodles")}")
    println("Entrees: $entrees")
    println("Add spaghetti: ${entrees.add("spaghetti")}")
    println("Entrees: $entrees")

    // Add a list of items using addAll()
    val moreItems = listOf("ravioli", "lasagna", "fettuccine")
    println("Add list: ${entrees.addAll(moreItems)}")
    println("Entrees: $entrees")

    // Remove an item using remove()
    println("Remove spaghetti: ${entrees.remove("spaghetti")}")
    println("Entrees: $entrees")
    println("Remove item that doesn't exist: ${entrees.remove("rice")}")
    println("Entrees: $entrees")

    // Remove an item using removeAt() with an index
    println("Remove first element: ${entrees.removeAt(0)}")
    println("Entrees: $entrees")

    // Clear out the list
    entrees.clear()
    println("Entrees: $entrees")

    // Check if the list is empty
    println("Empty? ${entrees.isEmpty()}")
}

MutableList 型の空のリストを作成するには次のようにします

val entrees = mutableListOf<String>()

こんな風に書くこともできます

val entrees: MutableList<String> = mutableListOf()

空のリストを作るときは型指定を忘れずに

  • mutableListOf() で最初に空のリストを作成するときは mutableListOf<型>() のようにして要素の型を指定しておきます
    • 初期化に使うデータがないのでどんな型のリストなのかKotlinが推測(infer)できないためです
    • List型のリストを生成する listOf() でも同様です。詳しくは こちら です
    • なお、ドキュメントの中で <T> のようにあらわされている T は「型」を意味します
  • MutableList は val で宣言することをお勧めします
    • mutableListOf() が返す MutableList 型の変数 entrees はリストへの参照(リストが保管されているメモリの場所)でリストそのものではありません
    • リストの要素に変更があってもリストの保管場所は変わらないため var である必要はありません
    • MutableList 型の変数が val で宣言されていてもリストの要素は変更できます

MutableList 型の変数の表示

println("Entrees: $entrees")

リストが空の時はつぎのように表示されます

Entrees: []

MutableList に要素を追加する

まず追加ですね

  • add・・・要素を追加する(結果をture/falseで返します)
println("Add noodles: ${entrees.add("noodles")}")
println("Entrees: $entrees")
  • addAll・・・要素をまとめて追加するときには追加する要素をリストにして addAll() を使う(結果をture/falseで返します)
val moreItems = listOf("ravioli", "lasagna", "fettuccine")
println("Add list: ${entrees.addAll(moreItems)}")
println("Entrees: $entrees")

MutableList から要素を削除する

うん、削除もしたいかも

  • remove(内容)・・・内容が一致する要素を削除する
    • 指定した内容の要素があって削除が成功したら true を返します
    • 要素の中に該当する内容がなければリストは変更されず false を返します
println("Remove spaghetti: ${entrees.remove("spaghetti")}")
println("Entrees: $entrees")
  • removeAt()・・・指定された index(添え字)位置の要素を削除する
    • removeAt(0) はリストの最初の要素を削除します
    • 戻り値は削除された要素の内容です
println("Remove first element: ${entrees.removeAt(0)}")
println("Entrees: $entrees")
  • clear()・・・リストの要素をすべて削除します
entrees.clear()
println("Entrees: $entrees")

MutableList が空かどうかチェックする

  • isEmpty()・・・リストが空(要素がひとつもない)かどうか判定します
println("Empty? ${entrees.isEmpty()}")

結果は true か false で返されるの

リストを使ってループ処理する

ぐるぐる回すんですね

  • リストの項目を処理したいとき、リストに対してループ処理(反復処理:iterating through)をします
  • ループ処理(loop through)は List にも MutableList にも可能です

While を使ったループ処理

添え字(index)を自分で管理します

サンプルプログラムです

val guestsPerFamily = listOf(2, 4, 1, 3)
var totalGuests = 0
var index = 0
while (index < guestsPerFamily.size) {
    totalGuests += guestsPerFamily[index]
    index++
}
println("Total Guest Count: $totalGuests")

実行結果は次の通りです

Total Guest Count: 10
  • while と index を使ってリストをループ処理しています
  • a += b は a = a + b と同じです
    • totalGuests += guestsPerFamily[index] は totalGuests = totalGuests + guestsPerFamily[index]
    • 引き算 (-=)、掛け算 (*=)、割り算 (\=) でも同じです。詳しくは こちら
  • index++ は index = index + 1 と同じです

for を使ったループ処理

ループの管理はKotlinにしてもらうの

なんかすっきり!

サンプルプログラムです

val names = listOf("Jessica", "Henry", "Alicia", "Jose")
for (name in names) {
    println("$name - Number of characters: ${name.length}")
}
  • リストをループ処理するには、while より for のほうが簡単です
  • for ( 変数 in リスト) { 処理 } のように書くと、変数に次々とリストの要素が代入されてリストの最後の要素まで自動的にループ処理されます
  • リストの要素の入った変数 name の length プロパティは、name に代入されている文字列の文字数をあらわします

for の繰り返しの書き方の例

いろんな書き方があるんですね

リストの要素をすべて表示する

for (item in list) print(item) // Iterate over items in a list

b から g までのアルファベットをすべて表示する

for (item in 'b'..'g') print(item) // Range of characters in an alphabet

1 から 5 までの数字をすべて表示する

for (item in 1..5) print(item) // Range of numbers

5 から 1 までの数字を降順にすべて表示する

for (item in 5 downTo 1) print(item) // Going backward

3 から 6 までの数字を1つおきに表示する(indexを+2ずつしながらループします)

for (item in 3..6 step 2) print(item) // Prints: 35

まとめ

リストって便利ですね

  • 同じ型のまとまったデータは Kotlin Standard Library で簡単に扱うことができます
  • まとまったデータを扱うのに、Kotlin では lists, sets, map といったデータ構造(コレクション:collection)が用意されています
  • このチュートリアルにでてきたリスト(list)は同じ型の要素が順に並んだデータ構造(コレクション)です
  • index(添え字)は要素の位置をあらわす整数で、0からはじまります
  • リストには List 型 と MutableList 型があります
  • List 型は初期化したあとは変更不可
  • List 型でも sorted() や reversed() は利用可能(新たに処理したリストを返すため)
  • MutableList 型は変更が可能
  • MutableList型の変数にリストにした要素をまとめて追加するには addAll() メソッドを使います
  • for (item in myList) { 処理内容 } でリストのループ処理ができます

参考