1. 程式人生 > >equals和hashcode和==

equals和hashcode和==

對Java來說:
在這裡插入圖片描述

==和=

==運算子的含義永遠是判斷兩個變數(常量也是一種特殊變數)的是否相等。
這裡的含義是:(=運算子進行的操作就是賦值)

  • 基本資料型別:值就是其值本身;
  • 引用資料型別的值就是其引用的物件的地址;

equals()和hashcode():

這是兩個從java.lang.Object物件繼承的可重寫的方法。

public class Object {
    public boolean equals(Object obj) {
        return (this == obj);
    }
    public
native int hashCode(); //native說明是用其他語言實現的,返回物件在記憶體中的地址 public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } ... }

根據規定
x.hashcode() == y.hashcode() 的值應與 x.equals(y) 值一樣。也就是說由x.equals(y)值應能 => x.hashcode() == y.hashcode()
(但是規定並不要求x.hashcode() == y.hashcode()

可以 => x.equals(y)值)
在重寫方法的時候要遵循這一規定。

以下描述中物件x和y相等的含義為x.equals(y) == true

Set容器中物件不能相等(Set的add方法會保證),但是物件的hashcode不一定不同。
HashSet為了提高物件比較效率,判斷兩個物件是否相等的實現是先判斷兩個物件的hashcode,若不同則認為兩個物件不相等,若相同則再呼叫equals方法判斷兩個物件是否真正的相等。
看以下程式:

public class Test {
    @Override
    public boolean equals(Object obj)
{ return true; } public static void main(String[] args) { HashSet<Test> h = new HashSet<Test>(); Test t1 = new Test(); Test t2 = new Test(); h.add(t1); h.add(t2); System.out.println(h.size()); //輸出2 } }

h.size()為2說明HashSet把兩個相等的物件判別為不相等。原因是我們在重寫equals方法時沒有遵守規定

對於java.lang.String類,equals方法返回兩個字串的字元序列是否相同:

public static void main(String[] args) {
    String s1 = new String("123");
    String s2 = new String("123");
    System.out.println(s1.equals(s2)); //true
    System.out.println(s1 == s2);      //false
}

對null的處理:
equals有以下規定:
對於任何非空引用值 x,x.equals(null)都應返回 false。

另外看下面程式執行結果:

public static void main(String[] args) {
    HashSet<Test> set = new HashSet<Test>();
    Map<Object, Object> map = new HashMap<Object, Object>();
    
    set.add(null);
    System.out.println(set.contains(null));   //true
    
    map.put("1", null);
    map.put(null, 1);
    System.out.println(map);                  //{null=1, 1=null}
    System.out.println(map.get(1));           //null
    System.out.println(map.get("1"));         //null
    System.out.println(map.get(null));        //1
}