1. ==
和 equals()
的区别
1.1 ==
基本数据类型,比较值
引用数据类型,比较内存地址
2.2 equals()
只能比较引用数据类型,没有重写时,比较对象的地址,重写后比较对象的内容
String
中的equals()
方法是被重写过的
在使用 equals()
方法时,应使用确定有值的对象来调用 equals()
,否则会抛出空指针异常
String str = null;
"SnailClimb".equals(str);// false
推荐使用 java.util.Objects#equals
(JDK引入的工具类),其源码如下:
public static boolean equals(Object a, Object b) {
// 可以避免空指针异常。如果a==null的话此时a.equals(b)就不会得到执行,避免出现空指针异常。
return (a == b) || (a != null && a.equals(b));
}
2. hashcode()
hashcode()
方法定义在 Object
类中,用来获取哈希码(散列码),返回一个 int 值(该对象在哈希表中的索引)。也就是说,只有在创建类的散列表(如:HashMap,HashTable,HashSet)时,hashcode() 才有用。
扩展:
hashcode()
是本地方法,用 C 或 C++ 实现,将对象的地址转换为整数返回。
为什么 hashcode()
提高性能?
以 HashSet
为例,当加入对象到 HashSet
中,会先计算对象的 hashcode 值,将其与已经加入的对象的 hashcode 值作比较,如果没有相同的,则说明该对象第一次出现,根据其 hashcode 值直接加入即可;如果有相同的 hashcode 值,这时会调用 equals()
方法判断 hashcode 值相等的对象是否真相等,如果相等,HashSet
不会让其加入成功,如果不相等(说明出现哈希冲突),则散列到其他位置。这样大大减少了 equals()
的次数,相应大大提高了性能。
3. 为什么重写 equals()
时必须重写 hashcode()
方法?
保证了“两个对象 equals 相等,那么地址也一定相同”的通用约定。 即如果重写了 equals()
而未重写 hashcode()
方法,可能就会出现两个对象 equals 相同,但 hashcode 值不同。hashCode()
的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode()
,则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。
如果两个对象相等,则
hashcode()
一定相等如果两个对象具有相同的
hashcode()
值,它们不一定相等(哈希冲突)