Kotlinの便利なところのメモ。
今回はdataクラス。
目次
<li>
<a href="#hashCode">hashCode()</a>
</li>
<li>
<a href="#componentN">componentN()</a>
</li>
<li>
<a href="#copytoString">copy(),toString()</a>
</li>
Kotlinのdataクラスとは#
classを宣言する時にdataとつけるとよく使う便利メソッドを勝手に実装してくれる仕組み。
//公式ページにある通りに書いた data class User(val name: String, val age: Int)
これだけでOK。簡単ですね。
ただし!
- プライマリコンストラクタは、少なくとも1つのパラメータを持っている必要があります。
- すべてのプライマリコンストラクタのパラメータは、
val
またはvar
としてマークする必要があります。- データクラスは、 abstract, open, sealed または inner にすることはできません。
- データクラスは他のクラスを拡張しない場合があります(ただし、インターフェイスを実装することはできます)。
(Kotlin公式リファレンスより)
だそうです。
最後の一文がどういう意味なのかちょっとわからないので要調査。
openにできないのでdataを利用したクラスを継承することはできないようです。
継承したくなること結構でてきそうですがその場合は自力で実装するんですかね。
何が起きるか#
- equals()が実装される
- hashCode()が実装される
- toString() で ”User(name=John, age=42)” に変換されるようになる
- componentN() が実装される
- copy() が実装される
へ〜
equals()#
equals()は文字通り二つのインスタンスの値が同じかどうかをチェックする時に使います。
以下テストコード。
//dataを利用したクラスの宣言。簡単。 data class User(val name: String, val age: Int) //testコード実行 test() fun test() { val userA = User("A", 10) val userA_ = User("A", 10) val userB = User("B", 10) if (userA.equals(userA_)) { println("AとA_は等しい") } else { println("AとA_は等しくない") } if (userA.equals(userB)) { println("AとBは等しい") } else { println("AとBは等しくない") } } //結果 AとA_は等しい AとBは等しくない
簡単ですね。
hashCode()#
その名の通りハッシュコードを返します。
公式リファレンスをgoogle翻訳したら結構いい感じだったのでそのまま引用
同じオブジェクトに対して複数回呼び出されるたびに、オブジェクトの等価比較で使用される情報が変更されない限り、hashCodeメソッドは常に同じ整数を返す必要があります。
equals()メソッドで2つのオブジェクトが等しい場合、2つのオブジェクトのそれぞれでhashCodeメソッドを呼び出すと、同じ整数の結果が生成される必要があります。
これといって特殊なことはありませんね。
直接利用することはそうそうないと思います。が一応動作確認コード。
data class User(val name: String, val age: Int) test() fun test() { println("Aのhashは%s".format(userA.hashCode())) println("A_のhashは%s".format(userA_.hashCode())) println("Bのhashは%s".format(userB.hashCode())) } //結果 Aのhashは2025 A_のhashは2025 Bのhashは2056
componentN()#
これが本日の目玉です。
Nとなっているとこには数字が入り(component1())メンバ変数(kotlinの場合厳密にはプロパティですかね)の数だけ 生成されます。
で、これがあることで何がいいかと言いいます、以下のような感じのことができるようになります。
data class User(val name: String, val age: Int) test() fun test() { val userA = User("A", 10) val (a,b) = userA println(a) println(b) } //結果 A 10
userAの値をそれぞれa,bに同時に代入しています。
componentN()メソッドが実装されることでこれが可能になります。
これは多分Kotlinの便利ポイントですね。
因みに独自クラスに自分で実装しても同じ機能が使えます。
copy(),toString()#
特に特殊なことはないしめんどくさいので割愛。
ということでkotlinの便利なdataクラスでした。
よく考えたらequalsとかは何も特殊じゃないのでコードいらなかった気がする。まあいいか。
ではまた。