== 、equals 、hashcode

 == 
. 基本数据类型比较的是值; 
. 引用类型比较的是地址值。

 equals(Object o)
1)不能比较基本数据类型,基本数据类型不是类类型; 
2)a.比较引用类型时(该方法继承自Object,在object中比较的是地址值)等同于”==”; 
Object类中的方法,所以,在每一个java类中,都会有这个方法,因为每一个java类都是直接或者间接的Object类的子类,会继承到这个方法。

2)b.如果自己所写的类中已经重写了equals方法,那么就安装用户自定义的方式来比较俩个对象是否相等,如果没有重写过equal方法,那么会调用父类(Object)中的equals方法进行比较,也就是比较地址值。

注:有的实现类中(JDK中),重写了equals方法,这时候比较内容(java.lang.String) 
在自定义类中,如果比较对象,自己可以重写equals方法定义比较规则。

注意:equals(Object o)方法只能是一个对象来调用,然后参数也是要传一个对象的。

所以下面是错误的写法: 
int a = 1; 
a.equals(1); 
因为基本数据类型不是算是对象,不能调用方法。

1)如果是基本数据类型那么就用==比较 
2)如果是引用类型的话,想按照自己的方式去比较,就要重写这个类中的equals方法, 
如果没有重写,那么equals和==比较的效果是一样的,都是比较引用的地址值。 
3)如果是比较字符串,那么直接用equals就可以了,因为String类里面已经重写了equals方法, 
比较的时候字符串的内容,而不是引用的地址值了。


--------------------- 
原文:https://blog.csdn.net/qq_42857603/article/details/81606707 

equals

Object 中

  public boolean equals(Object obj) {
        return (this == obj);
    }

很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们知道,String 、Math、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。

String 中

 1  /**
 2      * Compares this string to the specified object.  The result is {@code
 3      * true} if and only if the argument is not {@code null} and is a {@code
 4      * String} object that represents the same sequence of characters as this
 5      * object.
 6      *
 7      * @param  anObject
 8      *         The object to compare this {@code String} against
 9      *
10      * @return  {@code true} if the given object represents a {@code String}
11      *          equivalent to this string, {@code false} otherwise
12      *
13      * @see  #compareTo(String)
14      * @see  #equalsIgnoreCase(String)
15      */
16     public boolean equals(Object anObject) {
17         if (this == anObject) {
18             return true;
19         }
20         if (anObject instanceof String) {
21             String anotherString = (String)anObject;
22             int n = value.length;
23             if (n == anotherString.value.length) {
24                 char v1[] = value;
25                 char v2[] = anotherString.value;
26                 int i = 0;
27                 while (n-- != 0) {
28                     if (v1[i] != v2[i])
29                         return false;
30                     i++;
31                 }
32                 return true;
33             }
34         }
35         return false;
36     }

很明显,这是进行的内容比较,而已经不再是地址的比较。依次类推Math、Integer、Double等这些类都是重写了equals()方法的,从而进行的是内容的比较。当然,基本类型是进行值的比较。

hashcode

object中

   public native int hashCode();

说明是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖hashcode()方法,比如String、Integer、Double等这些类都是覆盖了hashcode()方法的。例如在String类中定义的hashcode()方法如下:

/**
     * Returns a hash code for this string. The hash code for a
     * {@code String} object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using {@code int} arithmetic, where {@code s[i]} is the
     * <i>i</i>th character of the string, {@code n} is the length of
     * the string, and {@code ^} indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    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;
    }

equals 默认是和==一样,判断引用是否相等的,一般需要覆写后才能实现真正的判等。

如果认为两个对象是 equal 的,那么最好使得这两个对象的 hashCode 值也是相等的,因为在往 Set 中加对象的时候,会首先用到对象的 hashCode 值。

它先根据 hashCode 来判断对象是否不相等,只要是不相等,HashSet 就认为他们肯定不是同一个对象,就可以省去 equals 的调用开销。

如果两个对象 equals 相等,但是 hashCode 不相等,会导致在 HashSet 中认为是两个不相等的对象,两个对象都会被加入到 HashSet,可能会导致程序异常。

猜你喜欢

转载自www.cnblogs.com/dingpeng9055/p/11065433.html