public native int hashCode()
hashCode()的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。另外需要注意的是Object的hashCode方法是本地方法,也就是用c或者c++实现的,该方法通常用来将对象的内存地址转换为整数之后返回。
散列表存储的是键值对(key-value),特点是能根据“键”快速的检索出对应的“值”,这其中就利用到了散列码(可以快速找到所需要的对象)
为什么要有hashCode
以HashSet如何检查重复为例:当把对象假如HashSet时,HashSet会先计算对象的hashCode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashCode值做比较,如果没相符的hashCode,HashSet会假设对象没有重复出现。但是如果发现有相同hashCode值得对象,这时就会调用equals方法来检查hashcode相等的对象是否真的相同,如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置,这样我们就大大减少了equals的 次数,相应就大大提高了执行效率。
hashCode()和equals的相关规定
1.如果两个对象相等,则hashCode一定也是相同的
2.两个对象相等,对两个对象分别调用equals方法都返回true
3.两个对象有相同的hashCode值,但是也不一定是相等的
4.因此,equals方法被覆盖过,则hashCode方法也必须被覆盖
5.hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode()。则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
为什么两个对象有想相同的hashcode值,他们也不一定是相等的?
因为hashCode()所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑度,越糟糕的杂凑算法越容易碰撞,但这也和数据值域分布的特性有关(所谓碰撞也就是指的是不同对象得到相同hashCode)
对于HashSet,如果HashSet在对比的时候,同样的hashcode有多个对象,它会使用equals来判断是否真的相同,也就是说hashcode只是用来缩小查找成本。
==与equals
==是判断两个对象的地址是不是相等。即判断两个对象是不是同一个对象(基本数据类型==比较的是值,引用类型==比较的是内存地址)
equals是判断两个对象是否相等。
1.类没有覆盖equals方法,则通过equals比较该类的两个对象时,等价于通过==比较两个对象
2.类覆盖了equals方法,一般我们都覆盖equals方法来判断两个对象的内容相等,则返回true
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一对象
System.out.println("a==b");
if (a.equals(b)) // true
System.out.println("aEQb");
if (42 == 42.0) { // true
System.out.println("true");
}
}
}
说明:
String中的equals方法是被重写过的,因为Object的equals方法比较的对象的内存地址,则String的equals方法比较的是对象的值。
当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋值给当前引用,如果没有就再常量池中重新创建一个String对象。