等価と等値の使い方（equalsの使い方）

###等価と等値の違い

先日受けたJavaSilverの試験結果にて不正解と思われる箇所として
・「＝＝とequals()を使用して文字列と他のオブジェクトが等しいかどうかをテストする」
が挙げられていたため、復習として記そうと思う。

参考[スッキリわかるJava入門](<table border="0" cellpadding="0" cellspacing="0"><tr><td><div style="border:1px solid #95a5a6;border-radius:.75rem;background-color:#FFFFFF;width:184px;margin:0px;padding:5px;text-align:center;overflow:hidden;"><table><tr><td style="width:80px"><a href="https://hb.afl.rakuten.co.jp/ichiba/1aecd7df.780bbf06.1aecd7e0.a0859005/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fbook%2F16099007%2F&link_type=picttext&ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJwaWN0dGV4dCIsInNpemUiOiI4MHg4MCIsIm5hbSI6MSwibmFtcCI6InJpZ2h0IiwiY29tIjoxLCJjb21wIjoiZG93biIsInByaWNlIjoxLCJib3IiOjEsImNvbCI6MSwiYmJ0biI6MSwicHJvZCI6MH0%3D" target="_blank" rel="nofollow sponsored noopener" style="word-wrap:break-word;"  ><img src="https://hbb.afl.rakuten.co.jp/hgb/1aecd7df.780bbf06.1aecd7e0.a0859005/?me_id=1213310&item_id=19815844&pc=https%3A%2F%2Fthumbnail.image.rakuten.co.jp%2F%400_mall%2Fbook%2Fcabinet%2F7807%2F9784295007807.jpg%3F_ex%3D80x80&s=80x80&t=picttext" border="0" style="margin:2px" alt="[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]" title="[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]"></a></td><td style="vertical-align:top;width:88px;"><p style="font-size:12px;line-height:1.4em;text-align:left;margin:0px;padding:2px 6px;word-wrap:break-word"><a href="https://hb.afl.rakuten.co.jp/ichiba/1aecd7df.780bbf06.1aecd7e0.a0859005/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fbook%2F16099007%2F&link_type=picttext&ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJwaWN0dGV4dCIsInNpemUiOiI4MHg4MCIsIm5hbSI6MSwibmFtcCI6InJpZ2h0IiwiY29tIjoxLCJjb21wIjoiZG93biIsInByaWNlIjoxLCJib3IiOjEsImNvbCI6MSwiYmJ0biI6MSwicHJvZCI6MH0%3D" target="_blank" rel="nofollow sponsored noopener" style="word-wrap:break-word;"  >スッキリわかるJava入門第3版 [ 中山清喬 ]</a><br><span >価格：2860円（税込、送料無料)</span> <span style="color:#BBB">(2020/8/7時点)</span></p></td></tr></table></div><br><p style="color:#000000;font-size:12px;line-height:1.4em;margin:5px;word-wrap:break-word"></p></td></tr></table>)


```java

public class Human {
  String name;
  int hp;

  public String toString(){
   return "name:" + this.name + "/age:" + this.age;
 }
}

```

上記のとき、
等値
-
(==)の判定
「完全に同一の存在」＝「同じアドレス値を指している」

```java:same.java
Human h1 = new Human("Taro")
Human h2 = h1;
```
ｈ２にh1を代入しているため、同じインスタンスA「name:Taro」をもち
参照先も同じ２１１２番地のアドレスを参照している。
このとき「h1 == h2」が成り立つ


等価
-


```java:equals.java
Human h1 = new Human("Ziro");
Human h2 = new Human("Ziro");
```
それぞれインスタンスを生成→参照している
インスタンスA「name:Ziro」　→　３３２２番地
インスタンスB「name:Ziro」　→　９１９１番地
「h1 != h2」が成り立つ
然し、文字列の内容は同じ
そのため「h1.equalsa(h2)」が成り立つ

うん、理解している。
が、
[スッキリわかるJava入門]([スッキリわかるJava入門])を進めていて後半のAPI活用の章に入ると
equals()は「何をもって同じとするか」という評価基準を指定しないと正しく動かない、と記載があるのだがちょっと混乱する。

以下は正しく動作しない
例１）二人の人物を比べる

```Java
public class Main {
  public static void main(String[] args) {
    Human h1 = new Human();
    h1.name = "Taro";
    h1.age = 10;    

    Human h2 = new Human();
    h2.name = "Taro";
    h2.age = 10;

    if ( h1.equals(h2) == true ) {
      System.out.println("Same");
    } else {
    System.out.println("different") ;
    }
  }
}

```
Objectクラスから継承されるequals（）の処理内容は以下の様に 
「とりあえず等値ならtrueを返しとく」
という形になる

```Java

public boolean equals(Object o) {
  if (this == o) { 
    return true; 
} else {
    return false;
  }
}
```

「何を持って同じ内容とみなすか」はそれぞれのクラスにより異なるので、
それぞれで定義しなければならない
つまり「equalsをオーバーライド」して指定する

条件が「名前が同じなら、同じHumanとみなす」
なら下記のようになる

```Java

public class Human {
 String name;
 int age;

public boolean equals(Object o ) {
  if (this == o) { 
  return true;
}  if (o instanceof Human) { // 以下追加オーバーライド ①oをHuman型にキャストできるか判定
  Human h = (Human)o;  // ②Object型o をダウンキャストしてHuman型にし、ｈに代入
  if ( this.name.equals(h.name)) {
    return true; 
    }  
   }
    return false;
  }
}


```


「SAME」と表示される