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 を、返しません。
つまり、その、インスタンスbL1bL2 の、実体/書き込まれたデータ は、
具体的には、PCの中の、同じ場所に無い、ので、「同じではない」 と、判断されました。
  / 10行目

でも、data class である、RedLineインスタンス の、
  rL1rL2 は、
  プロパティ が、同じ なので、自動で 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() も、分かりやすい結果になるように、オーバーライド してくれる。