19.0503
dataクラス(dataキーワード)
データクラス(data class)とは、データを格納するのに、最適化した/適している class です。
これを、実現するためには、
class の、前に、dataキーワード を、付けるだけ
です。
具体的には、何が最適化されるのでしょうか。
equals(other: Any): Boolean
/ == と、同じ.
hashCode(): Int
toString(): String
を、プログラマ が、自ら、override しなくても、よくなります。
equals(other: Any): Boolean
以前にも触れたと思いますが、
==
と同じであること。
value-type/値型 以外は、全く同じ「もの」 でないと、true を、返さない。
これが、どのように最適化されるのか?
それは、
プロパティ が等しいかを、比べる
ようになります。
ためしに、こんなコードを書いてみました。
これは、架空の車名 BlueLine と、RedLine で、
type(何年型): Int color(車の色): String
という プロパティ で、class にしました。
BlueLine は、普通のclass として、
RedLine は、data class としました。
普通の、class BlueLine は、プロパティ を、同じように設定しても、
equals() は、true を、返しません。
つまり、その、インスタンスbL1、bL2 の、実体/書き込まれたデータ は、
具体的には、PCの中の、同じ場所に無い、ので、「同じではない」 と、判断されました。
/ 10行目
でも、data class である、RedLineインスタンス の、
rL1 と rL2 は、
プロパティ が、同じ なので、自動で override されている equals() は、
「同じである」 と、判断しました。
/ 20行目
もし、この、自動で override されている equals() を、自前で、
override しようとしたら、簡単ではありません。
とりあえず、プロパティ に絞っての、override は、それほどには、難しくはありませんが(手間ですが)、
equals() として、設定するには、
hushCode() の返す数値 も、一致させなければならない
というルール があります。
そうしないと、不具合が出る可能性があります。
しかし、その問題は、
class に、dataキーワード を付けるだけで、解決できるのです。
ただ、制限されていることがあります。
・ プライマリコンストラクタ(コード参照)に、書かれているプロパティのみ が、比べる対象になる
・ そのコンストラクタ の 引数 は、val または var を、使う事。
・ abstract/open/sealed/innerクラス には、使えない。
わたしも、sealedクラス は、知りませんが、もし、期待通りの動きをしない時は、チェックしてみましょう。
また、dataキーワード を、指定した時点で、IDEなら、違反を、指摘するとは、思われますが?
toString() の、override
また、toString()メソッド も、オーバーライドしてくれます。
どんなふうに、オーバーライド/override してくれるのか、調べました。
RedLine(type=2015, color=red)
こんな風に、表示されました。
BlueLine@17f6480
より、ずっと分かりやすくなりました。
まとめ
・ data classでは、
equals(other: Any): Boolean
/ == と、同じ.
hashCode(): Int
toString(): String
を、自動で、オーバーライド して、使いやすくしてくれる。
・ equals() を、オバーライドする時には、hashCode() も、オバーライド しなくてはならない。
・ デフォルトの、equals() は、プロパティ が、同じと言うだけでは、true を、返さない。
value-type/値型 以外では、全く同じもの でないと、true を返さない。
・ data class では、プロパティ が、同じかどうかを調べる。
・ ただし、data class では、プライマリコンストラクタ(class のすぐ後)のみが、
equals() で、比較する対象になる。
・ data class で、守ること:
- プライマリコンストラクタ(コード参照)に、書かれているプロパティのみ が、比べる対象になる
- そのコンストラクタ の 引数 は、val または var を、使う事。
- abstract/open/sealed/innerクラス には、使えない。
・ data class では、toString() も、分かりやすい結果になるように、オーバーライド してくれる。