Kotlinで複数の値を格納できる型の代表格といえば配列(Array)、コレクション型のList、Set、Mapですが、今回はコレクションに分類されるListの基本についてお話しようと思います。
Listの特徴
Listの特徴としては、
- 値を複数格納できる、コレクション型を継承した型である
- 読み込み専用、変更可能の2つのバージョンがある
- 順番を持ち、インデックス番号で値にアクセスする
- 値の重複が許される
この4つがあります。3,4に関しては配列と同じです。
実際配列とListには共通する操作方法も多いですが、あくまで配列は「コレクション」の一員ではありません。
継承元のクラスが違うという実装面での大きな違いはありますが、押さえておきたいのは、配列はよりプリミティブ(基礎的、原始的)な型であり、コレクションはそれをより柔軟に、便利に扱うために拡張された型であるということです。
そのため実際の開発では、配列を使うことよりもListやMapを使用することの方が圧倒的に多くなるかと思います。
Listの作成と基本操作
では早速、Listを作成してみましょう。読み取り専用のList型インスタンスを作成するにはlistOf関数、変更可能なMutableList型であればmutableListOf関数を使用します。
fun main() {
val lst = listOf("二重","えくぼ","涙袋")
val lst2 = mutableListOf(1,2,3)
println(lst)
println(lst2)
}
//[二重, えくぼ, 涙袋]
//[1, 2, 3]
配列の場合は標準出力するのにArrays.toString()に渡す必要がありましたが、Listではそのまま標準出力できます。
その他の基本的な操作に関しては配列と共通する部分も多いので、共通する操作に関しては駆け足でご紹介しています。配列の操作も合わせてご確認ください。
型パラメータ
型パラメータはString型を格納したListの場合List<String>、数値を格納したMutableListであればMutableList<Int>となります。
値の指定方法
println(lst[0])
//二重
配列と同じようにインデックス番号で値を指定します。配列の記事で使用したgetOrElse、getOrNullメソッドも使用可能です。
また値の取得、代入にはget、setメソッドを使用することもできます。
println(lst.get(2)) //涙袋
lst2.set(0,10)
println(lst2) //[10, 2, 3]
get(インデックス番号)で値の取得、set(インデックス番号,新しい値)で値の変更を行っています。
なお当然ですが、setはMutableListでしか使えませんので注意しましょう。
要素数を取得
println(lst.size)
//3
配列と同じくsizeプロパティで要素数を取得することができます。
Listのループ処理
for(i in lst){println(i)}
lst2.forEach{print(it)}
forやforEachに関しても配列と同じ記述方法で使用できます。
MutableList – 値の追加と削除
ここからはMutableListのお話に移っていきます。
配列、List、MutableListとある中で、最もフレキシブルに扱えるのはMutableListであり、他のスクリプト言語で配列やリストといえば、こちらの形をイメージされる方も多いと思います。
後から要素数を変更できるということで、MutableListではこのような初期化の方法もあります。
val mtl = mutableListOf<String>()
この時点ではMutableListに要素はありません。行っているのは「変数mtlは将来、String型が入るMutableListです」という宣言だけです。
Listの場合もこの方法での初期化は一応可能ですが、その後に要素数を追加していくことができないため、あまり現実的ではありません。配列は要素数を追加することも可能ですが、前回ご紹介したnull埋め配列などの方がより一般的です。
しかし、Listや配列の「(基本的に)要素数が固定である」という制限は、安全性という観点から言えばメリットにもなります。そのListが可変である必要があるのか、不変で構わないのか、よく考えて選択することが重要です。
「nullという値すら不要」「要素の枠数を限定したくない」という場合はMutableListを使用しましょう。
値を追加する
MutableListに値を追加するにはaddメソッドを使用します。引数には代入する新たな値が入り、すでに要素がある場合は、全ての要素の末尾に指定した値が追加されます。
mtl.add("はじめしゃちょー")
このaddメソッドは2つの引数を取ることもできます。その場合、第一引数は追加するインデックス番号、第二引数に代入する値を指定します。
mtl.add(1,"HIKAKIN")
mtl.add(1,"Fischer's")
println(mtl)
//[はじめしゃちょー, Fischer's, HIKAKIN]
2回目のaddではインデックス1に"Fischer’s"を代入しています。すでに値が存在するインデックスであった場合、追加される値以降はインデックス番号が1つ後ろに移動します。
メソッドの代わりに演算子で追加することもできます。内部的にはメソッド呼び出しと等価です。
mtl+="はじめしゃちょー"
複数の値を追加する
複数の値を一気に追加したい場合、addAllメソッドで追加することができます。
mtl.addAll(listOf("はじめしゃちょー","HIKAKIN","Fischer's"))
addAllメソッドの内部ではListを新規作成し、そのListを変数に代入すること無く、全ての内容を既存のMutableListに追加しています。
または+=演算子を使って、同じように複数項目を追加することもできます。
mtl+=listOf("木下ゆうか","東海オンエア","SUSHI RAMEN")
さらに以前お話したスコープ関数を使って、連続して値を追加することも可能です。ここではapplyを使用しています。
mtl.apply{
add("水溜りボンド")
add("AAAjoken toys")
add("SeikinTV")
}
MutableListから値を削除する
MutableListに代入されている値を削除するには、第一の手段としてremoveメソッドがあります。
mtl.remove("HIKAKIN")
引数には値そのものが入ります。これで"HIKAKIN"をMutableListから削除することができます。
こちらも先程と同様、演算子に置き換えることも可能です。
mtl-="HIKAKIN"
インデックス番号を指定して削除するのであれば、removeAtメソッドです。引数には削除したいインデックス番号を指定してください。
mtl.removeAt(3)
条件を指定して削除する
ある条件に合致した値を削除したい場合、removeIfを使ってみるのもいいでしょう。
fun main() {
val mtl = mutableListOf<String>()
mtl.addAll(listOf("はじめしゃちょー","HIKAKIN","Fischer's"))
mtl+=listOf("木下ゆうか","東海オンエア","SUSHI RAMEN")
mtl.removeIf { it.contains("I") }
println(mtl)
}
//[はじめしゃちょー, Fischer's, 木下ゆうか, 東海オンエア]
このコードの5行目では、removeItとcontainsメソッドを使って、6組のYouTuberから大文字の"I"が含まれるものだけを削除しています。
removeIfの中身はラムダ式です。MutaleListの中身を1つ1つitとして参照しているのが分かると思います。
containsメソッドは、引数に取った文字列(や数値)が呼び出し元に含まれる場合、trueを返します。trueになった場合のみremoveが働き、要素を削除しています。
全ての要素を削除する
MutableListの中身を丸ごと削除するにはclearメソッドです。
mtl.clear()
このメソッドでは引数は不要です。変数自体は削除されませんので、新たに変数宣言するのではなく、同じ変数を使って新たなリストを作成するような場合に使いましょう。
おさらい
今回はコレクション型の初回として、
- List型の特徴と基本操作
- MutableListに値を追加する
- MutableListから値を削除する
以上の基本的なことについてお話しました。
次回は同じくコレクション型のSetについて。