はじめに
Kotlinの公式サイトを基にListとSetとMapの違いについて学んだことをまとめる。
本記事の対象者はKotlin初心者、プログラミングを初めたばかりの人向けの記事である。
この記事の執筆のきっかけ
とある勉強会でKotlinの技術についてのLTがありました。
名前は知っていたけど使ったことがなかったので公式サイトでサンプルプログラミングを動かしてみようと見てみたら、かなり丁寧もドキュメントが書かれていてサンプルコードもたくさんあってびっくりしました。
ListとSetとMapについてまとめてあったページはKotlinを使用していない人にとっても有益だと思い、
KotlinでのListとSetとMapについて学んだことをまとめてみようと思いました。
公式サイトの今回教材にしたページはこちら。
ListとSetとMapとは
例えば、あなたがキャパ100人の学園祭の受付係だったとします。
キャパを超える人数は絶対に園内に入れるなとリーダから言われました。
100人に達しているかどうかを知りたいだけなら、紙のリストバンドを100枚用意して
入園希望者に渡していき、用意していたリストバンドが無くなったら、それ以降の入園希望者にお断りをすれば良いです。これがSetです。
しかし、ゾロ目の入園者にはプレゼントを渡すイベントを計画していたら、Setではうまくいきません。 入園した順番を管理する必要があるので、リストバンドに1から番号を記入していかないといけません。 この番号付きリストバンドがListです。
また、入園時間に応じてお菓子がもらえるイベントがあるとListでもうまくいきません。 入園者と入園時間を管理する必要があります。 そのためには、リストバンドを渡す時に、現在時刻を入園時間としてリストバンドに記入してから渡す必要があります。こういったように、何かの情報を紐づけて管理することがMapです。
この例えからなんとなく違いがイメージできたでしょうか。
ListとSetとMapを表にまとめると以下のようになります。
この表はKotlin公式サイトにも載っています。
タイプ | 特徴 |
---|---|
List | アイテムの順序付きコレクション |
Set | 順序のないユニークなアイテムのコレクション |
Map | キーと値のペアの集合で、キーが一意であり、1つの値にのみマップされるもの |
ではListとSetとMapについて簡単に説明したところで、
Kotlinの公式を見ながらListとSetとMapの使い方を確認します。
List
ここからは公式ページに書いてある順に説明します。
公式ページは英語で書かれていますし、時々難しい表現があるので、
理解しにくい部分をサポートできるように簡素に書きます。
ListにはList
とMutableList(ミュータブルリスト)
の2種類あります。
Listを作るときはlistOf
で、要素を設定し、
MutableListを作るときは、mutableListOf
で設定をします。
こんな感じ。
// Read only list
val readOnlyShapes = listOf("triangle", "square", "circle")
// Mutable list with explicit type declaration
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
List
はReadOnly、つまり一度listOfで作成した後は、要素の追加や変更、削除はできません。
MutableList
は逆に要素の追加や変更、削除ができます。
List(またはMutableList)は上で書いた学園祭の例えでは順番を書いてあるリストバンドなので、
番号を指定したり、first()
と書いて最初の要素を指定することもできます。
こんなかんじ。
//MutableListでも同じだよ
val readOnlyShapes = listOf("triangle", "square", "circle")
println("The first item in the list is: ${readOnlyShapes[0]}")
//出力結果は下のとおり
// The first item in the list is: triangle
println("The first item in the list is: ${readOnlyShapes.first()}")
//出力結果は下のとおり
// The first item in the list is: triangle
また、count()
を使って要素の数を数えることもできます。こんな感じ。
val readOnlyShapes = listOf("triangle", "square", "circle")
println("This list has ${readOnlyShapes.count()} items")
//出力結果は下のとおり
// This list has 3 items
他には、in
を使って要素があるかどうかを見つけることもできます。
出力結果はtrue
かfalse
です。
こんな感じ。
val readOnlyShapes = listOf("triangle", "square", "circle")
println("circle" in readOnlyShapes)
//出力結果
// true
今度は、MutableListだけになりますが、要素を追加したり、削除したりする方法です。
追加するときはadd()
、削除するときはremove()
を使います。こんな感じ。
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
// "pentagon" を追加するよ
shapes.add("pentagon")
println(shapes)
//出力結果は以下のとおり。
// [triangle, square, circle, pentagon]
// "pentagon" を削除するよ
shapes.remove("pentagon")
println(shapes)
//出力結果は以下のとおり。
// [triangle, square, circle]
Listはこんな感じで終わりです〜
Set
Setは上の学園祭の例でいうと番号無しリストバンドです。
SetにもSet
とMutableSet
があります。Listと同じで
単なるSetは変更不可、MutableSetは変更できます。
Setの最初の設定はこんな感じ。それぞれsetOf
かmutableSetOf
を使います。
// Read-only set
val readOnlyFruit = setOf("apple", "banana", "cherry","cherry")
// Mutable set with explicit type declaration
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
println(readOnlyFruit)
//出力結果は以下のとおり。
// [apple, banana, cherry]
setは同じ要素があったら一つと見なされます。
なので、上のコードをよく見るとSetOfやmutableSetOfで"cherry"が2つあるのですが、出力結果では"cherry"は一つです。
学園祭に入った人が一度学園から出て、また入ってきても2つ目のリストバンドは渡さないみないな感じです。
逆にListの場合は同じ要素でも追加できます。
学園祭に入った人が一度学園から出て、また入ってこようとしたら順番が変わってるから2つ目のリストバンドを渡しちゃおうって感じです。
setは順番を持っていないのでlistのように番号を指定することはできません。できるのは何個の要素があるかを知ることと要素がsetの中にあるかどうかを知ること、あとはlistでもあった追加と削除です。listと同じでそれぞれcount()
、in
、add()
、remove()
を使います。
countとinのコードはこんな感じです。
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
//要素の数が知りたいとき
println("This set has ${readOnlyFruit.count()} items")
//出力結果は以下のとおり。
// This set has 3 items
//指定の要素があるかどうか知りたいとき
println("banana" in readOnlyFruit)
//出力結果は以下のとおり。
// true
addとremoveはこんな感じです。
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
fruit.add("dragonfruit") // Add "dragonfruit" to the set
println(fruit) // [apple, banana, cherry, dragonfruit]
fruit.remove("dragonfruit") // Remove "dragonfruit" from the set
println(fruit) // [apple, banana, cherry]
Setはこんな感じで終わりです。
ListもSetもどっちかが優位でどっちかが劣位というわけではなく、
ListがいいかSetがいいかは作るシステムの特性を見て決めないといけないですね。
Map
最後はMapです。
Mapも変更不可のMap
と変更可能なMutableMap
があります。
Mapを設定するときはmapOf
、MutableMapを設定するときはmutableMapOf
を使います。
この辺はListやSetと似ています。
ただ、Mapは上で書いた学園祭の例えで言うと入園時間記載ありのリストバンドなので
入園時間と入園者名というように二つの情報を紐づけるためにto
を使います。
to
の左側をKey
、右側をvalue
と呼びます。
コードはこんな感じ。
// Read-only map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
// Mutable map with explicit type declaration
val accountBalances: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)
value
を取ってきたいときはkey
を指定します。
入園者名を知りたいとき、入園時間で検索するイメージです。
コードはこんな感じ。
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println("The first value in the map is: ${readOnlyAccountBalances[1]}")
// 出力結果は以下の通り。
// The first value in the map is: 100
また、ListやMap同様にcount()
を使ってkeyとvalueのペア数を知ることもできます。
コードはこんな感じ。
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println("This map has ${readOnlyAccountBalances.count()} key-value pairs")
// 出力結果は以下の通り。
// This map has 3 key-value pairs
MutableMapだけになりますが、追加と削除はput()
、remove()
でできます。
ListとSetのときは追加はadd()
でしたがMapのときはput()
であることに注意が必要です。
コードはこんな感じ。
val accountBalances: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)
// keyが4でvalueが100という要素を追加する
accountBalances.put(4, 100)
println(accountBalances)
// 出力結果はこんな感じ。
// {1=100, 2=100, 3=100, 4=100}
//keyが4の要素を削除
accountBalances.remove(4)
println(accountBalances)
// 出力結果はこんな感じ。
// {1=100, 2=100, 3=100}
keyが存在しているか確認するときはcontainsKey()
が必要です。
keyは一意になるものじゃないといけないのでcontainsKey()で確認をしましょう。
出力結果はすでにkeyが存在していたらtrue
、存在していなかったらfalse
となります。
学園祭の例えではkeyを一意にするために、入園時間の秒数まで記入しないといけないですね。
コードはこんな感じ。
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(readOnlyAccountBalances.containsKey(2))
// 出力結果はこんな感じ。
// true
また、keyだけを知りたいときやvalueだけを知りたいときはkeys
やvalues
を使います。
コードはこんな感じ。
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(readOnlyAccountBalances.keys)
// 出力結果はこんな感じ。
// [1, 2, 3]
println(readOnlyAccountBalances.values)
// 出力結果はこんな感じ。
// [100, 100, 100]
最後にcontainsKey()
ではない方法で指定のkeyがすでに存在するか調べる方法と、
指定のvalueがすでに存在する方法になります。
どちらもin
を使って調べることができます。
出力結果はどちらも存在していたらtrue
、存在していなかったらfalse
となります。
コードはこんな感じ。
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(2 in readOnlyAccountBalances.keys)
// 出力結果はこんな感じ。
// true
println(200 in readOnlyAccountBalances.values)
// 出力結果はこんな感じ。
// false
Mapはこれで終わりになります。
List、Set、Mapの説明やサンプルコードは全て公式サイトを引用させていただきました。
公式サイトは英語で書かれていますが、シンプルに説明されていて、とても有益です。
参考資料
Kotlinを学ぶためのサイトを紹介します。
私も全部は確認できていませんが、それぞれ読んでみたり使ってみました。
Kotlin Programming Language
Kotlinの公式サイトです。まずはここを見ましょう。
Kotlin Playground
Kotlinを環境構築なしでブラウザ上で動かすことができます。
公式サイトのコードをコピペしたり、一部を変えてコードの動きを確認しました。
Kotlin for Developers - App Development Guides
Android Appの公式サイトになります。いつかスマホアプリをリリースするのが夢です。
最後に
Kotlin公式サイトには基本的な文法の学習以外にも、Ktorを使ってHTTP APIsを作るサンプルコードがあったり、Androidアプリの作成方法があったり、まだまだ勉強できることはたくさんあるので確認していきます〜。