初学者必须知道的Java中 equals & hashCode方法的应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linglaoli/article/details/84401986

方法的定义

  1. equals
    Java中的每个类都直接或间接继承至Object类。如果子类没有重写此方法,那么就默认调用父类的方法:
    public boolean equals(Object obj) {
        return (this == obj);//直接比较2个对象是否相等,这里比较2对象的内存地址
    }
        //直接调用内部方法
    public native int hashCode();

而android中hashCode的实现方式是:

    public int hashCode() {
            return identityHashCode(this);
    }
    public native int hashCode();
    /* package-private */ static int identityHashCode(Object obj) {
        int lockWord = obj.shadow$_monitor_;
        final int lockWordStateMask = 0xC0000000;  // Top 2 bits.
        final int lockWordStateHash = 0x80000000;  // Top 2 bits are value 2 (kStateHash).
        final int lockWordHashMask = 0x0FFFFFFF;  // Low 28 bits.
        if ((lockWord & lockWordStateMask) == lockWordStateHash) {
            return lockWord & lockWordHashMask;
        }
        return identityHashCodeNative(obj);
    }
    
    @FastNative
    private static native int identityHashCodeNative(Object obj);

hashCode方法直接都要调用本地native方法。java 源码中,获取对象的地址,将地址转换为整数值来作为哈希码。
在java中哈希值的用处是在哈希表(HashMap,HashTable)中,哈希表根据对象的哈希值将对象散列到不同位置。对象的哈希值越不容易重复,那么对于哈希表的效率就越高,因为目前的散列方法是分离链接法。如果对散列想进一步了解请转到 数据结构–散列总结

equals方法重写

对于原始的方法实现,我们是不满足的。举个栗子,对象如下:

public class Banner {

    @Expose
    @SerializedName("errno")
    private String error;

    @Expose
    @SerializedName("errmsg")
    private String errmsg;
        public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }
}

        Banner b1 = new Banner();
        b1.setError("error 1");
        Banner b2 = new Banner();
        b2.setError("error 1");

那么此时,b1.equals(b2)是等于false.那么我们如何去改进呢。
一般重写equals方法有一下几个步骤

  1. 检查对象是否为空
  2. 判断对象是否是本类类型
  3. 转换到本类类型对象
  4. 比较本类中的重点属性值是否相等

比如我们看String类的实现:

    public boolean equals(Object anObject) {
        if (this == anObject) {//因为是final类,不可改变,对象的创建都是生成新的对象
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = count;
            if (n == anotherString.count) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = offset;
                int j = anotherString.offset;
                while (n-- != 0) {
                    if (v1[i++] != v2[j++])
                        return false;
                }
                return true;
            }
        }
        return false;
    }

equals & hashCode 的关系

equals hashCode
true 对象相同,他们的hash值应该相等
false 对象不同,hash值应该不相等

具体关系,他们之间没必然联系,因为我们对2个方法的要求会不一样,关注的对象属性可能不一样。

猜你喜欢

转载自blog.csdn.net/linglaoli/article/details/84401986