📦

[Kotlin]複数の要素をキーとしたMapを作るならPairが便利

2022/06/06に公開

2つの要素をキーとしてMapを作りたい場合、Pairクラスを利用すると便利です。
例えば、名前毎に入金と出金のそれぞれの合算値を知りたい場合は以下のように書けます。

fun main() {
    val records = mapOf(
        Pair("Aさん", "入金") to 2000,
        Pair("Aさん", "出金") to 1080,
        Pair("Bさん", "入金") to 500,
	Pair("Aさん", "出金") to 110,
	Pair("Aさん", "入金") to 1000,
	Pair("Aさん", "出金") to 980,
        Pair("Bさん", "出金") to 180,
        Pair("Cさん", "入金") to 500,
        Pair("Bさん", "出金") to 50,
        Pair("Cさん", "入金") to 1000,
    )
    
    for ((k,v) in records) {
    	println("$k = $v")
    }
}

結果は以下。

(Aさん, 入金) = 1000
(Aさん, 出金) = 980
(Bさん, 入金) = 500
(Bさん, 出金) = 50
(Cさん, 入金) = 1000

Mapのキーにクラスを使う場合に気をつけなければならないのが、equals()メソッドが実装されている事です。
equalsメソッドは、data classでは標準で実装されており、Pairクラスはdata classなのです。
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/

従って、Pairクラスでなくとも、自前のdata classを用意すれば同じことが出来ます。
上で示した例を独自data classで書き換えてみます。

data class Factor(
    val name: String,
    val io: String
)

fun main() {
    val records = mapOf(
        Factor("Aさん", "入金") to 2000,
        Factor("Aさん", "出金") to 1080,
        Factor("Bさん", "入金") to 500,
	Factor("Aさん", "出金") to 110,
	Factor("Aさん", "入金") to 1000,
	Factor("Aさん", "出金") to 980,
        Factor("Bさん", "出金") to 180,
        Factor("Cさん", "入金") to 500,
        Factor("Bさん", "出金") to 50,
        Factor("Cさん", "入金") to 1000,
    )
    
    for ((k,v) in records) {
    	println("$k = $v")
    }
}

結果は以下。

Factor(name=Aさん, io=入金) = 1000
Factor(name=Aさん, io=出金) = 980
Factor(name=Bさん, io=入金) = 500
Factor(name=Bさん, io=出金) = 50
Factor(name=Cさん, io=入金) = 1000

Pairを利用していた時と同様の結果が得られている事がわかります。
そして独自のdata classであれば要素は2つ以上持つこともで出来るので応用の幅も広がります。

ちなみに、data classを利用しなかった場合はどのようになるでしょうか。

data class Factor

から

class Factor

にしてしまうと以下のようになります。

Factor@5910e440 = 2000
Factor@6267c3bb = 1080
Factor@533ddba = 500
Factor@246b179d = 110
Factor@7a07c5b4 = 1000
Factor@26a1ab54 = 980
Factor@3d646c37 = 180
Factor@41cf53f9 = 500
Factor@5a10411 = 50
Factor@2ef1e4fa = 1000

ただの個別のインスタンスとして扱われてしまい、データがバラバラに登録されてしまいました。

という事で、便利なdata classを使っていきましょう!
ちなみに、data classについて別の記事も書いてますので是非こちらも読んでみて下さい。
https://qiita.com/highcom/items/2eb99b29d72d96f35dd3

Discussion