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