6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

Kotlinの公式サイトで学ぶListとSetとMapの違いと使い方

Posted at

はじめに

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にはListMutableList(ミュータブルリスト)の2種類あります。
Listを作るときはlistOfで、要素を設定し、
MutableListを作るときは、mutableListOfで設定をします。
こんな感じ。

List
// 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()と書いて最初の要素を指定することもできます。
こんなかんじ。

List
//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()を使って要素の数を数えることもできます。こんな感じ。

List
val readOnlyShapes = listOf("triangle", "square", "circle")
println("This list has ${readOnlyShapes.count()} items")
//出力結果は下のとおり
// This list has 3 items

他には、inを使って要素があるかどうかを見つけることもできます。
出力結果はtruefalseです。
こんな感じ。

List
val readOnlyShapes = listOf("triangle", "square", "circle")
println("circle" in readOnlyShapes)
//出力結果
// true

今度は、MutableListだけになりますが、要素を追加したり、削除したりする方法です。
追加するときはadd()、削除するときはremove()を使います。こんな感じ。

List
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にもSetMutableSetがあります。Listと同じで
単なるSetは変更不可、MutableSetは変更できます。
Setの最初の設定はこんな感じ。それぞれsetOfmutableSetOfを使います。

Set
// 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()inadd()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はこんな感じです。

Set
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と呼びます。
コードはこんな感じ。

Map
// 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を指定します。
入園者名を知りたいとき、入園時間で検索するイメージです。
コードはこんな感じ。

Map
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のペア数を知ることもできます。
コードはこんな感じ。

Map
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()であることに注意が必要です。
コードはこんな感じ。

Map
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を一意にするために、入園時間の秒数まで記入しないといけないですね。
コードはこんな感じ。

Map
val readOnlyAccountBalances = mapOf(1 to 100, 2 to 100, 3 to 100)
println(readOnlyAccountBalances.containsKey(2))
// 出力結果はこんな感じ。
// true

また、keyだけを知りたいときやvalueだけを知りたいときはkeysvaluesを使います。
コードはこんな感じ。

Map
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となります。
コードはこんな感じ。

Map
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アプリの作成方法があったり、まだまだ勉強できることはたくさんあるので確認していきます〜。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?