1、Object的HashCode定义html
1 public native int hashCode();
Object类的hashCode方式使用了native修饰也就意味着真正的实现调用的其余语言编写的方法,咱们能够忽略具体的实现,从方法的定义上能够看出,hashCode实际上是一个int型的整数java
如下是hashCode()这个方法的官方解释算法
Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. The general contract of hashCode is: Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the java.lang.Object.equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables. As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
解释一下数组
一、hashcode()这个方法主要为了给hash系列的集合(HashMap、HashTable、HashSet)提供支持缓存
二、一个应用在一次执行过程当中调用同一个对象的hashcode()方法返回值是同样的,屡次执行(关闭应用再启动)应用程序返回值可能不一致。由此推测hashcode()底层实现方法跟内存地址有关。app
三、若是两个对象进行equals比较返回True,那么这两个对象的hashcode()方法必须返回一样的值。在一些重写equals方法的场合务必注意重写hashcode方法以便于达到这样的要求。关于equals的介绍能够参照这篇文章《Java-从堆栈常量池解析equals()与==》ide
四、是两个对象equals--->hashcode相等,可是hashcode相等并不能推出两个对象equals。缘由是hashcode的计算方法是对象的某种属性进行的数学运算后获得的值,不免会出现两个不一样的对象(equals返回false)得出同样的hashcode(一般状况几率极小)post
2、String对象的hashcodeui
1 public int hashCode() { 2 int h = hash; 3 if (h == 0 && value.length > 0) { 4 char val[] = value; 5 6 for (int i = 0; i < value.length; i++) { 7 h = 31 * h + val[i]; 8 } 9 hash = h; 10 } 11 return h; 12 }
其中hash是一个缓存,一个String对象计算过hashcode以后就不用再次计算了,由于即便是再次计算它的值仍是同样的。value是String对象(由一个个字符构成)的字符数组this
算法其实实现了这么一个逻辑运算:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],n表明String的长度,简单吧:hashcode就是一个算数运算后的int值,它通常能够惟一标识一个对象,若是遇到两个不一样的对象hashcode同样(几率很小),还要看同样两个对象是否equals。总之仍是能够区分开的。
3、对象为何要有hashcode这个属性
前面提到hashcode能够给hash系列的集合提供支持,那么也就是说hash系列的容器须要这个属性才设置的这个属性,那么为何要有hash系列的容器呢?
容器的主要做用是存储对象,检索对象。一般状况下:
①、Array直接经过索引检索对象速度极快,可是Array的特色是一旦肯定容量就不能变化了
②、Collection,Map的之类解决了容器容量变化的问题,咱们知道他们的实现类有不少,也是各有各的特色,园子里有位达人总结的很好参照:《Java 集合系列目录(Category)》。
区别主要:
a)、Array能够存放基本类型数据,集合类存储的是Object
b)、List中元素是可重复的有序的(可经过get(index)方法返回元素,Set中元素是不可重复的而且是无须的(没法经过索引取到元素),List、Set元素是单一的,Map中的元素是key-value对
c)、插入数据,检索数据,修改数据三方面的效率上看能够理解为ArrayList基于数组实现检索数据效率高插入修改数据效率高,LinkedList基于链表实现插入修改数据效率高检索数据效率低
d)、HashSet与TreeSet主要是有序无须的差异,后者能够有序遍历Set中的元素
e)、同理HashMap与TreeMap的区别与d中所述一直由于d是基于e实现的
③、hash系列的容器其实主要是为了解决了容器插入数据,检索数据,修改数据效率折中的问题而产生的,用hashcode标识对象在集合中的位置对于排序,检索,修改数据都较快。