java中的==、equals方法和hashCode方法

一、==和equals的区别

1、==比较运算符
 (1)基本数据类型:比较的是值是否相等
 (2)引用数据类型:比较的是地址是否一样
2、equals[object]方法
 (1)基本数据类型:不可以使用equals进行比较
 (2)引用数据类型:没有重写过equals方法则使用object中的equals方法,本质上是使用==,比较的是地址
 (3)String类型:源码重写了equals方法,先比较两个的地址是否一样,一样就返回true,不一样再比较值是否一样(代码如下)。

public boolean equals(Object anObject) {
    //先比较地址
    if (this == anObject) {
        return true;
    }
    //地址不一样再来看是不是String类型,然后对值进行比较
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
           }
           return true;
        }
    }
    return false;
}

二、Object中的hashCode方法及equals方法和hashCode方法的重写

hashCode方法:没有被重写的object中原生的hashCode值是根据内存地址换算出来的一个值。

在Object.hashCode()中对hashCode方法的解释:
1、在一个应用程序执行期间,同一个对象上多次调用hashCode,则返回的值都是相同的整数,前提是该对象上的equals比较中的信息没有被修改。
2、如果两个对象根据equals方法是相等的,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果。
3、如果两个对象根据equals方法是不相等的,那么在两个对象中的每个对象上调用hashCode方法不要求必须产生不同的整数结果。但是,为不相等的对象产生不同的整数结果可能会提高哈希表的性能。
4、通常是通过将对象的内部地址转换为整数来实现hashCode值,但是你也可以自己实现hash算法,即重写hashCode方法。

也就是说:
 两个对象根据equals方法是相等的,那么他们的hashCode值也相等;
 两个对象根据equals方法是不相等的,那么他们的hashCode值可以相等也可以不相等;
 两个对象hashCode值相等,他们的equals不一定相等;

为什么重写equals方法后也要重写hashCode方法?

在业务中有时候不需要严格意义上的相等,只需要满足业务要求的对象相等就可以,所以我们就需要根据我们的业务来重写equals方法。

我们重写了equals方法后,如果没有重写hashCode方法,就违反上面说的第2点,所以我们还需要再重写hashCode方法。

String类中重写的hashCode方法:

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

在Object类中关于equals方法和hashCode方法的约定:

/**
 * hashCode---java.lang.Object
 * 1、只要在Java应用程序执行期间在同一对象上多次调用它,hashCode方法就必须始终返回相同的整数,
 * 前提是在该对象的equals比较中使用的信息没有被修改。 从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。
 * 2、如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
 * 3、根据equals(java.lang.Object)方法,如果两个对象不相等,则在两个对象中的每一个上调用hashCode方法不需要产生不同的整数结果。
 * 但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
 * 4、在合理可行的范围内,由类Object定义的hashCode方法确实为不同的对象返回不同的整数。
 * (通常通过将对象的内部地址转换为整数来实现,但是这种实现技术对于Java编程语言来说不是必须的。
 */
/**
 * equals---java.lang.Object
 * 指示其他某个对象是否与此对象“相等”。
 * equals方法对非null对象引用实现对等关系:
 * 1、自反性:对于任何非空参考值x,x.equals(x)应该返回true。
 * 2、对称性:对于x和y的任何非空引用值,当且仅当y.equals(x)}返回true时,x.equals(y)才返回true。
 * 3、可传递性:对于x,y和z的任何非空引用值,如果x.equals(y)返回true,而y.equals(z)返回true,则x.equals(z)应该返回true。
 * 4、一致性:对于任何非空引用值x和y,如果未修改对象的equals比较中使用的信息,则多次调用x.equals(y)始终返回true或始终返回false。
 * 对于任何非null的参考值,x,x.equals(null)应该返回false。
 * 类Object的equals方法在对象上实现了最有区别的对等关系。 也就是说,对于任何非空参考值x和y,当且仅当x和y引用相同的对象(x == y的值为true)时,
 * 此方法才返回true。
 * 请注意,通常有必要在重写此方法时重写hashCode方法,以维护hashCode方法的常规协定,该协定规定相等的对象必须具有相等的哈希码。
 */

写在最后:

  • 如果文章中有错误或是表达不准确的地方,欢迎大家评论中指正,以便我完善。
  • 文章我也会根据所学到新的知识不断更新。

你可能感兴趣的:(java中的==、equals方法和hashCode方法)