关于种的equals和hashcode方法

关于类的equals和hashcode方法
当我们想要改写equals方法的时候,总是应该打起12分的精神,不然稍不留神,就能跑出来一些让你抓狂的错误。

先看个例子:

package general;


import static java.lang.System.out;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class TestEffective {

    public static void testEqualsValue() {
        PhoneNumber a = new PhoneNumber(755, 4397681, "calvin");
        PhoneNumber c = new PhoneNumber(755, 4397681, "calvin");
        out.println(a.equals(c));

        Set s = new HashSet();
        s.add(a);
        s.add(c);
        out.println(s.size());

        HashMap<PhoneNumber, String> h = new HashMap<PhoneNumber, String>();
        h.put(new PhoneNumber(755, 4397681, "calvin"), "my number");
        out.println(h.get(new PhoneNumber(755, 4397681, "calvin")));
    }

    public static void main(String args[]) {
        testEqualsValue();
    }
}

class PhoneNumber {
    int area;
    int number;
    String name;

    public PhoneNumber(int area, int number, String name) {
        super();
        this.area = area;
        this.number = number;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof PhoneNumber)) {
            return false;
        }
        
        PhoneNumber oPhone = (PhoneNumber) obj;
        if (this.area == oPhone.area
                && this.number == oPhone.number
                && (oPhone.name == null ? this.name == null : this.name
                        .equals(oPhone.name))) {
            return true;
        } else {
            return false;
        }
    }

    // @Override
    // public int hashCode() {
    // int result=17;
    // result=37*result+area;
    // result=37*result+number;
    // return result;
    // }

}



粗略一看,结果应该打出, true, 1, "my number"

而实际运行结果确是  true, 2, null

其原因在于违反了改写equals的规则,需要同时也改写hashcode方法。

总体来说,改写equals的时候,需要默念的几条规则如下:

1. 如果equals的对象的引用指向相同,为节省效率,直接返回ture
2. 如果equals的对象是null,那么直接放回false
3. 如果类型不同,直接返回false
4. 如果类型相同而且各个值也相等,值域比较考虑Null值,返回true
5. 同时也改写hashcode方法,设定一个足够散的值


最后,再检查一遍,

a等于b, 那么是否b也等于a
a等于b, b等于c,那么a也等于c
a等于b, 是否不管执行多少便,都是true,是否依赖外界环境