java.lang.Object类中有两个比较重要的方法:
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
1.hasCode()方法详解
理解hash code之前,先理解hash表
1.1hash表
hash表:根据关键码值(Key value)而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(hash)表,函数f(key)为哈希(hash) 函数。
举个例子
hash表M长为n = 13,存在一个hash函数f(key) = key % n
key = {6, 37,49,28,46,12,13},然后依次把这些key带入hash函数中,便可得出对应的hash code。
如:key = 6,f(6) = 6 % 13 = 6,则,key = 6的hash code 为6
简单来说:在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。
1.1hash code是什么?
- 从文档上看,hashCode()方法给对象返回一个hash code值(int型)。这个方法被用于hash tables,例如HashMap。
- 从方法本身来看,它是个本地方法,它的实现是与本地机器相关的。hash code是通过对象的内存地址经过hash算法得到的
String、Integer、Double等这些类都是覆盖了hashCode()方法的
1.2hash code作用
hash code的存在主要是为了查找的快捷性(提高效率)。hash code是用来在散列存储结构中确定对象的存储地址的
对于容器类设计 基本上都会涉及到hash code。hashCode()方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap、HashTable等。
在对集合进行插入操作时,有些集合内部是不允许存在重复元素的,这样就引发了一个问题
如何判断在集合中是否已经存在该对象了?
首先想到的方法就是调用equals()方法,这个方法确实可行。但是如果集合中已经存在大量的数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。
此时hashCode方法的作用就体现出来了:当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hash code值。如果table中没有该hash code值,它就可以直接存进去,不用再进行任何比较了;如果存在该hash code值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。这样一来实际调用equals方法的次数就大大降低了。
简而言之,在集合查找时,hashcode能大大降低对象比较次数,提高查找效率!
2.equals()详解
equals()方法是用来判断其他的对象是否和该对象相等.
equals()方法在object类中定义如下:
public boolean equals(Object obj) {
return (this == obj);
}
很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是,String 、Math、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法,都是进行对内容的比较
【注意】:当equals()方法被override时,hashCode()也要被override。因为按照一般hashCode()方法的实现来说,相等的对象,它们的hash code一定相等。
Java对于eqauls方法和hashCode方法是这样规定的:
- equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。
- hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。