深入理解Java集合框架系列-第二章、Java集合中的hashCode方法
来源:互联网 发布:hibernate sql注入 编辑:程序博客网 时间:2024/06/05 06:16
众所周知,Java中的集合框架有三大类,一类是List,一类是Set,另一类是Queue。List内的元素是有序的,元素可以重复。Set元素无序,但元素不可重复。要想保证元素不重复,两个元素是否重复应该依据什么来判断呢?用Object.equals方法。但若每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说若集合中已有10000个元素,那么第10001个元素加入集合时,它就要调用10000次equals方法。这显然会大大降低效率。那么有没有更好的方法了?
Java中数据存储方式最底层的两种结构,一种是数组,另一种就是链表,数组的特点:连续空间,寻址迅速,但是在删除或者添加元素的时候需要有较大幅度的移动,所以查询速度快,增删较慢。而链表正好相反,由于空间不连续,寻址困难,增删元素只需修改指针,所以查询慢、增删快。
有没有一种数据结构来综合一下数组和链表,以便发挥他们各自的优势?答案是肯定的!就是:哈希表。哈希表具有较快(常量级)的查询速度,及相对较快的增删速度,所以很适合在海量数据的环境中使用。一般实现哈希表的方法采用“拉链法”,我们可以理解为“链表的数组”,见上图:
从上图中,我们可以发现哈希表是由数组+链表组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。它的内部其实是用一个Entity数组来实现的,属性有key、value、next。
当HashMap、HashTable、HashSet等集合对象接收一个元素时,默认根据该对象的内存地址算出hashCode,看它属于哪一个具体的数组元素,在这个数组元素里调用equeals方法。这么做确实提高了效率。但一个面临问题:若两个对象equals相等,但不在一个数组元素里,根本没有机会进行比较,会被认为是不同的对象。所以Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同。也告诉我们重写equals方法,一定要重写hashCode方法。
2、如果两个对象的hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。
如下代码,如果没有重写hashCode()和equals(),则输出3,如果重写hashCode()和equals(),则输出值为1。Coordinate的代码请查看上一篇文章。
Coordinate c1=new Coordinate(12,34);
Coordinate c2=new Coordinate(12,34);
Coordinate c3=new Coordinate(12,34);
Set<Coordinate> sets=new HashSet<Coordinate>();
sets.add(c1);
sets.add(c2);
sets.add(c3);
System.out.println(sets.size());
- 深入理解Java集合框架系列-第二章、Java集合中的hashCode方法
- 深入理解Java集合框架系列-第一章Java对象的hashCode哈希码
- 《深入理解Java集合框架》系列文章
- 《深入理解Java集合框架》系列文章
- 深入理解Java集合框架系列-第四章java中的队列
- 深入理解Java集合框架系列-第五章 java中的堆栈
- 深入理解Java集合框架系列 -第七章 ArrayList
- 深入理解Java集合框架系列 -第六章 Java集合框架Deque
- Java系列-集合框架理解
- 深入理解Java集合框架系列-第三章 使用集合排序
- 深入理解Java之集合框架
- 深入理解Java之集合框架
- 深入理解Java集合
- java集合框架系列
- Java hashCode() 方法深入理解
- 深入了解java集合框架中的常用集合
- java中的equals和hashCode方法以及集合的排序
- 黑马程序员-Java中的hashCode()方法和hashSet集合
- 【hdu 4497】GCD and LCM 【算术基本定理】
- [bzoj2788][Poi2012]Festival floyd 差分约束系统 tarjan
- Android中touch事件机制学习总结
- 顶部标题栏在页面滚动后逐渐淡出
- c++ template报错
- 深入理解Java集合框架系列-第二章、Java集合中的hashCode方法
- centos下修改文件后如何保存退出
- React去掉双击文字的选中状态
- 监听服务器端口
- MapView跟Scrollview冲突
- 06-Ubuntu-Linux基础命令
- 欢迎使用CSDN-markdown编辑器
- 数据库SQL实战
- java端实现文件下载