Effective Java----2

来源:互联网 发布:中国当下的网络环境 编辑:程序博客网 时间:2024/05/29 13:40

1.equals方法以及HashCode方法
重写equals方法满足如下的约定
(1) 自反性(feflexive)
(2) 对称性(symmetric)
(3) 传递性(transitive)
(4) 一致性(consistent)

这几个特性都比较容易理解,违反其中任何一条,都将导致重写的equals方法不能正常工作,具体实施起来,即要按如下步骤重写equals方法:

(1) 使用==操作符检查”参数是否为这个对象的引用”,如果是这个对象的引用,表明是同一对象,满足上述4个特性,返回true.
(2) 使用instanceof操作符检查”参数是否为正确的类型”。
(3) 将参数转换成正确的类型。
(4) 对于该类中的每个”关键域(significant)”,检查参数中的域是否与该对象中对应的域相等。
(5) 检查是否满足上述的四个特性。
还有一定要注意必须要覆盖hashCode方法!
下面的类按照以上步骤重写了equals方法,只是还没有覆盖hashCode方法:

import java.util.HashMap;import java.util.Map;public class PhoneNumber {    private short areaCode;    private short prefix;    private short lineNumber;    public PhoneNumber(int areaCode,int prefix,int lineNumber)    {        rangeCheck(areaCode,999,"area code");        rangeCheck(prefix,999,"prefix");        rangeCheck(lineNumber,9999,"lineNumber");        this.areaCode = (short) areaCode;        this.prefix = (short) prefix;        this.lineNumber = (short) lineNumber;    }    private static void rangeCheck(int arg, int max, String name) {        if (arg < 0 || arg > max)            throw new IllegalArgumentException(name +":" + arg);    }    public boolean equals(Object o)    {        if (o == this)            return true;        if (!(o instanceof PhoneNumber))            return false;        PhoneNumber pn = (PhoneNumber)o;        return pn.lineNumber == lineNumber &&                pn.prefix == prefix &&                pn.areaCode == areaCode;    }    public static void main(String[] args)    {        Map<PhoneNumber,String> m = new HashMap<PhoneNumber,String>();        m.put(new PhoneNumber(707,867,5309), "Jennny");        System.out.println(m.get(new PhoneNumber(707,867,5309)));       }}

此时运行结果为null,由于没有覆盖hashCode方法,两个本来相等的对象却拥有不同的hashCode,因此结果为null.这时候需要我们设计一个恰当的散列函数来实现hashCode方法,既要保证相同对象有相同值,不同对象hashCode值尽量不相同,又不能使计算散列函数的计算开销过大,比如,上例中的hashCode方法可以这样来设计:

public int hashCode(){    int result = 17;    result = 31 + result + areaCode;    result = 31 + result + prefix;    result = 31 + result + lineNumber;    return result;}

这时候再运行上述程序就可以得到正确结果了。

1 0
原创粉丝点击