【Kotlin練習問題】コレクション:基礎(List, Set, Mapとは)

コレクションとは

コレクション(Collection)とはSet、List、Mapといった型のことで、複数の値を格納したり、格納した値に番号を割り振ることで任意の値を取り出したりすることができるものです。

それらはコレクションヒエラルキーというものに属しており、根幹にはCollection<T>というインターフェースがあります。このインターフェースはそのコレクションのサイズを読み込んだり、値を調べるといった読み込み専用コレクションの基本的な挙動を表すものです。

Collectionは繰り返し処理を定義しているIterable<T>インターフェースを継承しています。

またCollectionを関数のパラメーターとして設定すると以下のコードのように、異なる型のコレクションにも適用させることができます。

fun printAll(strings: Collection<String>) {
        for(s in strings) print("$s ")
        println()
    }
    
fun main() {
    val stringList = listOf("one", "two", "one")
    printAll(stringList) //ここではList型が渡されている
    
    val stringSet = setOf("one", "two", "three")
    printAll(stringSet) //ここではSet型が渡されている
}

以下ではList、Set、Map、それぞれの違いを説明していきます。

Listとは

List<T>は指定された順番で要素を格納し、それぞれに紐づいたインデックス番号を振り分けます。番号は最初の要素が0から始まり、最後の要素がlastIndexになります。lastIndexはリストの要素数から1を引いた(list.size – 1)と表すこともできます。

val numbers = listOf("one", "two", "three", "four")
println("Number of elements: ${numbers.size}")
println("Third element: ${numbers.get(2)}")
println("Fourth element: ${numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")

//出力結果
//Number of elements: 4
//Third element: three
//Fourth element: four
//Index of element "two" 1

Listの要素(nullを含む)は重複することもあります。同じリスト内に何個でも等しいオブジェクトがあったり、一つのオブジェクトが何回も使われることがあります。

リスト同士は同じサイズ(要素数が同じ)で同じ位置に同じ要素がある場合、等しいものとみなされます。

val bob = Person("Bob", 31)
val people = listOf(Person("Adam", 20), bob, bob)
val people2 = listOf(Person("Adam", 20), Person("Bob", 31), bob)
println(people == people2) //true
bob.age = 32
println(people == people2) //false

Setとは

Set<T>一意性を持つ(かぶりがない)要素を格納します。通常順番は定義されていません。null要素も同様に一意であり、一つのSetにはnullは一つしか含むことができません

Set同士はサイズが同じ(要素数が同じ)で、Setのそれぞれの要素と等しい要素がもう一方のSetに含まれていれば等しいものとみなされます。

val numbers = setOf(1, 2, 3, 4)
println("Number of elements: ${numbers.size}")
if (numbers.contains(1)) println("1 is in the set")

val numbersBackwards = setOf(4, 3, 2, 1)
println("The sets are equal: ${numbers == numbersBackwards}")

//出力結果
//Number of elements: 4
//1 is in the set
//The sets are equal: true

Mapとは

冒頭でListやSet、Mapはコレクションヒエラルキーに属していると説明しましたが、実はMap<K, V>だけはCollectionインターフェースを継承していません。しかし他の型と同様にMapもKotlinコレクション型の一つです。

Mapはキーと値(またはエンティティ)のペアを格納します。キーには一意性がありますが、異なるキーが等しい値と紐づけられていることもありえます。Mapインターフェースにはキーで値にアクセスしたり、キーや値を検索するなどといった関数が定義されています。

/val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)

println("All keys: ${numbersMap.keys}")
println("All values: ${numbersMap.values}")
if ("key2" in numbersMap) println("Value by key \"key2\": ${numbersMap["key2"]}")    
if (1 in numbersMap.values) println("The value 1 is in the map")
if (numbersMap.containsValue(1)) println("The value 1 is in the map") //上のコードと同じ意味

//出力結果
//All keys: [key1, key2, key3, key4]
//All values: [1, 2, 3, 1]
//Value by key "key2": 2
//The value 1 is in the map
//The value 1 is in the map

Map同士は等しいペアを格納をしていれば、ペアの順番に関係なく等しいものをみなされます。

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)    
val anotherMap = mapOf("key2" to 2, "key1" to 1, "key4" to 1, "key3" to 3)

println("The maps are equal: ${numbersMap == anotherMap}") //true

問題

Kotlinスタンダードライブラリにはコレクションをより便利に活用するための拡張関数が数多く含まれています。例えば、あるコレクションを別の型のコレクションに変換するための ‘to‘から始まる関数です。(toSetやtoListなど)

拡張関数Shop.getSetOfCustomers()を実装してください。Shopクラスと全ての関連するクラスはShop.ktに含まれています。

問題コード:

fun Shop.getSetOfCustomers(): Set<Customer> =
        TODO()

Shop.kt

data class Shop(val name: String, val customers: List<Customer>)
​
data class Customer(val name: String, val city: City, val orders: List<Order>) {
    override fun toString() = "$name from ${city.name}"
}
​
data class Order(val products: List<Product>, val isDelivered: Boolean)
​
data class Product(val name: String, val price: Double) {
    override fun toString() = "'$name' for $price"
}
​
data class City(val name: String) {
    override fun toString() = name
}
[expander_maker id=”1″ more=”答え” less=”非表示”]

答え

fun Shop.getSetOfCustomers(): Set<Customer> =
        customers.toSet()
[解説]

Shopクラスに含まれているCustomersはList<Customer>型なので、Set<Customer>型に変換する必要があります。問題はじめで説明したように、Kotlinスタンダードライブラリには既にコレクション型を別のコレクション型に変換する関数が含まれているので、それを活用すれば簡単にListからSetに変換することができます。

[/expander_maker]

その他の問題はこちらからどうぞ。

完全無料で通えるプログラミングスクール

プログラミング学習はどうしても一人だとつまづいてしまう時がきます。調べればわかることも少なくないですが、最初のうちは調べ方もわからないことが多いため、あまり効率的ではありません。

効率的かつ挫折せずにプログラミングを学習したい方はスクールを検討してみるのも一つの手です。

中には無料で通えるスクールや、就職保証をしてくれるスクールなどもあるので、きっとあなたの目的に応じて最適のスクールが見つかります!以下の記事で評判がよく特におすすめのスクールをいくつかピックアップしているので、スクール選びで後悔したくない方は御覧ください!

https://codelabsjp.net/best-programming-school/

おすすめ書籍

Kotlinの文法をまず学びたい!という方には以下の書籍がおすすめです。Kotlinは日本語書籍がまだ豊富とは言えない状況ですが、細かく解説されており、Kotlin入門者のかたでもつまずくことなく学習できると思います。

[itemlink post_id=”1743″]

実際にアプリを作りながら覚えていきたい!という方には以下もお勧めです。はじめに上の書籍で文法をさらっと学んでから取り組むのがお勧めです。

[itemlink post_id=”1745″]