在網上搜到一條題目挺有意思的,需要好好理解 Java 裡的 hashcode()Equals()

# Question

  1. Question: Why the amap size is 3? Instead of 4 even though we called put() method 3 times *
  2. Question 2: Fixed the code(Apple class) * to let the map treat the apples with the same color as the same key. * So the amap size will be 1. Output should be "map size is 1" * * DO NOT Change the main method */

# Code

a
package com.tiffanyiong;  
  
import java.util.Collection;  
import java.util.Collections;  
import java.util.List;  
import java.util.Scanner;  
import java.util.*;  
  
public class Main {  
  
  
 public static void main(String[] args) {  
        Apple a = new Apple("red", 10);  
        Apple a1 = new Apple("red", 10);  
        Apple a2 = a;  
        Apple a3 = new Apple("red", 10);  
  
        Map<Apple, String> amap = new HashMap<>();  
        amap.put(a,"one apple");  
        amap.put(a1,"two apples");  
        amap.put(a2,"three apples");  
        amap.put(a3,"four apples");  
  
        System.out.printf("map size is %s \n", amap.size());  
  
        System.out.println(a3.equals(a1));  
  
  
    }  
  
    }  
  
class Apple {  
    private int price;  
    private String color;  
    HashSet<String> set = new HashSet();  
  
    public Apple(String color, int price) {  
        this.price = price;  
        this.color = color;  
  
    }  
  
    public int getPrice() {  
        return price;  
    }  
  
    public void setPrice(int price) {  
        this.price = price;  
    }  
  
    public String getColor() {  
        return color;  
    }  
  
    public void setColor(String color) {  
        this.color = color;  
    }  
  
    @Override  
 public String toString() {  
        return "Apple{" +  
                "color='" + color + '\'' +  
                '}';  
    }  
  
   
}

# 解答

  1. == Operator 和 java 裡 equals () 是有區別,可以想像 == 是個 pointer, 我只是把 a2 point to a 這個 APPLE 的 Object,所以第一題應該是 3 個 objects, size 也只會是 3, 由始至終只有 3 個 objects
  2. 需要重新寫 hashcode () 和 equals () 的方法

# Object 裡的 equals ()

Human a = new Human("tiff");
Human b = a;
a.equals(b);  
Human c = new Human("tiff");
a.equals(c); // false

(click the answer below)

  1. 上面代碼的 a.equals(b) 是___?

    • true
    • false
  2. 上面代碼的 a.equals(c) 是___?

    • true
    • false

    首先看一下,為甚麼 a.equals(c) 是錯的

    • 因為 Object Class 裡面的 equals() 只是對比 obj == obj , 而此時 c 是新的一個 object, 儘管裡面的值是相等,但並不代表它們是一樣。
    • 比如:同時有兩個人叫小明,但他們是不是同一個人?他們只是名字相同而已。
      可是,不啊,這就是小明,這就是一個人而已! 那我們可以 Override equals ()!
      但是在此之前,要先看看 String 裡的 equals()

# String class - equals()

我們再來看看這個代碼

String s1 = new String("ab");  
String s2 = new String("ab");  
System.out.println(s1.equals(s2));
  1. 上面代碼的 s1.equals(s2) 是___?
    • true
    • false
String 的equals()

沒錯,如果看源碼的話,String 裡的 equals () 是重新寫的!
這不再像之前的 object 一樣 obj == obj ,這次是比較 Obj 裡面的值啦~
所以我們知道 String 和 Object 裡的 equals () 是比較不樣的的東西後,我們就知道了,其實可以寫自己的 equals ()! 不過我們還需要知道 hashCode ()

題外話: StringBuilder 沒有 Override equals() , 不能用來 Compare, 2 個 StringBuilder 的 object 用 equals() 肯定不對啦

# hashCode

  • Each object has a unique memory address which helps the object class hashCode to generate an unique hashcode for each object.
    • it uses memory address, then do some calculation

JVM gen't get the actual memory address, that's why it do some pre-processing to create a hashcode

A Good HashCode:
a good hashcode() should return a distinct integer for each object (as much as possible). tow different object can have the same hashcode();

  1. same hashcode != same object
  2. but if the objects are the same, then the hashcode will be the same

# Solution Code

@Override  
 public boolean equals(Object o) {  
        if (this == o) return true;  
        if (o == null || getClass() != o.getClass()) return false;  
        Apple apple = (Apple) o;  
        return color.equals(apple.color)
    }  
  
    @Override  
 public int hashCode() {  
         return Objects.hash(color);  
  
    }