Java--神奇的hashcode
一、Object的HashCode定义
public native int hashCode();
Object类的hashCode方式使用了native修饰也就意味着真正的实现调用的其他语言编写的方法,我们可以忽略具体的实现,从方法的定义上可以看出,hashCode其实是一个int型的整数
以下是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.)
解释一下
1、hashcode()这个方法主要为了给hash系列的集合(HashMap、HashTable、HashSet)提供支持
2、一个应用在一次执行过程中调用同一个对象的hashcode()方法返回值是一样的,多次执行(关闭应用再启动)应用程序返回值可能不一致。由此推测hashcode()底层实现方法跟内存地址有关。
3、如果两个对象进行equals比较返回True,那么这两个对象的hashcode()方法必须返回同样的值。在一些重写equals方法的场合务必注意重写hashcode方法以便于达到这样的要求。关于equals的介绍可以参照这篇文章《Java-从堆栈常量池解析equals()与==》
4、是两个对象equals--->hashcode相等,但是hashcode相等并不能推出两个对象equals。原因是hashcode的计算方法是对象的某种属性进行的数学运算后得到的值,难免会出现两个不同的对象(equals返回false)得出一样的hashcode(通常情况概率极小)
二、String对象的hashcode
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;
}
其中hash是一个缓存,一个String对象计算过hashcode之后就不用再次计算了,因为即使是再次计算它的值还是一样的。value是String对象(由一个个字符构成)的字符数组
算法其实实现了这么一个逻辑运算:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],n代表String的长度,简单吧:hashcode就是一个算数运算后的int值,它一般可以唯一标识一个对象,如果遇到两个不同的对象hashcode一样(概率很小),还要看一样两个对象是否equals。总之还是可以区分开的。
三、对象为什么要有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标识对象在集合中的位置对于排序,检索,修改数据都较快。
Java--神奇的hashcode的更多相关文章
- 浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...
- java中的hashcode
hashcode的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode.在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括 ...
- 千万不要误用 java 中的 HashCode 方法
刚才debug追堆栈的时候发现一个很奇怪的问题 我用IE8和Google的浏览器访问同一个地址 Action的 scope="session" 也设置了 而且两个浏览器提交的参数m ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- java :equals()和hashcode()方法的结合使用
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...
- K:java中的hashCode和equals方法
hashCode和equals方法是Object类的相关方法,而所有的类都是直接或间接的继承于Object类而存在的,为此,所有的类中都存在着hashCode和equals.通过翻看Object类 ...
- Java 基础:hashCode方法
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 一.前言 泥瓦匠最近被项目搞的天昏地暗.发现有些要给自己一些目标,关于技术的目标: 专注很重要.专注J ...
- 【转】浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...
- Java中的hashcode方法
一.hashCode方法的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode.在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列 ...
- java 中的 hashcode
在Java的Object类中有一个方法: public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没 ...
随机推荐
- 网络编程(Socket)
引言: 从2007年毕业开始一直从事.net web应用程序开发,负责冶金行业的MES系统开发,写了差不多6年左右的代码,由于工作性质是需要驻厂开发,一直出差,所以在2013年跳槽了,目前从事安防行业 ...
- 折腾 Phalcon 的笔记
不要用 IIS!Apache 万岁! 不要用 Web Platform Installer!自己动手丰衣足食! 注意版本号.TS 与 NonTS.x86 与 x64 的区别! 关于 Apache 的配 ...
- 再也不用克隆多个仓库啦!git worktree 一个 git 仓库可以连接多个工作目录
我在 feature 分支开发得多些,但总时不时被高优先级的 BUG 打断需要临时去 develop 分一个分支出来解 BUG.git 2.6 以上开始提供了 worktree 功能,可以解决这样的问 ...
- JavaScript年月日和时间戳互转
/** 一丶将日期单位转为时间戳 / 毫秒 **/ var str="2017年06月2日" var time = str.replace(/年/i,"-"). ...
- LeetCode 760. Find Anagram Mappings
原题链接在这里:https://leetcode.com/problems/find-anagram-mappings/description/ 题目: Given two lists Aand B, ...
- Request对象主要用于获取来自客户端的数据,如用户填入表单的数据、保存在客户端的Cookie等。
1.主要属性 ApplicationPath 获取服务器上asp.net应用程序的虚拟应用程序根路径 Browser 获取有关正在请求的客户端的浏览器功能的信息,该属性值为:HttpBrows ...
- vue插件vue-infinite-loading的使用
vue-infinite-loading官网:https://peachscript.github.io/vue-infinite-loading/ 安装: npm install vue-infin ...
- WebSocket的使用
WebSocket是长连接,如果客户端的程序没有数据实时同步的需求就没必要使用它.因为长连接会带来一定的服务器内存开销.如果Ajax就能轻松搞定的话就完全没必要兴师动众的搞WebSocket. htt ...
- elastic search6.2.2 实现用户搜索记录查询(去重、排序)
elastic search6.2.2 实现搜索记录查询 ,类似新浪微博这种,同样的搜索记录后面时间点的会覆盖前面的(主要思路:关键词去重,然后按时间排序) 先创建索引 //我的搜索 PUT my_s ...
- Protobuff java 文件生成命令
protoc.exe -I./proto文件目录 --java_out=java文件目录 proto文件基于文件目录的全路径 protoc.exe -I./protoFolder --java_out ...