要想知道一个元素是否在数组或链表中,只能从前向后挨个对比,无论是数组还是链表,其对数据的查询表现都比较无力。在的二叉排序树中,还会将数据排序以进行二分查找,将时间复杂度从O(n)降低到O(lg n)。

出现这个问题的根源在于,我们没有办法直接根据一个元素找到它存储的位置。

那有没有办法消除这个对比的过程呢?哈希表就是解决查询问题的一种方案。

什么是哈希表与Hash函数

通俗来讲,哈希表就是通过关键字来获取数据的一种数据结构,它通过把关键字映射为表中的位置来获取元素,这种映射主要是使用Hash函数。

因为不同需求需要的key类型不一致,可能是int,可能是String,也可能是其他任意对象。但是内存地址却不能以这些对象来寻址,因而Hash函数的作用就是把这些对象通过合理的方式转为int类型,从而完成数据的存储。Hash函数需要保证的是对于相同的key,其计算结果总是相同的。

这个过程就好比我们用拼音查字典。如果要查一个字,我们不会从第一页到最后一页挨着看,这将需要很长的时间,而是根据其发音先在拼音表中找到对应的页数,直接定位到对应的页即可。当然,由于有许多发音一致的汉字,所以我们可能依然需要逐个对比,但这复杂度就小太多了。

哈希表的过程就和上述例子一致,我们根据元素的key,通过hash函数直接定位其位置。然而类似于许多汉字的发音一致一样,也会有许多的key通过hash函数定位的结果一致,这就是发生了所谓的哈希碰撞。

解决哈希碰撞的方法

比较通用的方法,就是使用数组+链表组合的方式。当出现哈希碰撞时,在该位置的数据就通过链表的方式链接起来,如图所示:

在JDK1.7及之前的版本中,HashMap的存储结构和上图是一致的,在JDK1.8之后还加入了红黑树以进一步优化。

哈希表的优缺点

哈希表是一种优化存储的思想,具体存储元素的依然是其他的数据结构。

设计良好的哈希表,能同时兼备数组和链表的优点,它能在插入和查找时都具备良好的性能。

设计不好的哈希表,有可能会出现较多的哈希碰撞,导致链表过长,从而哈希表会更像一个链表。还有当数据量很大时,为防止链表过长,就需要对数组进行扩容,这时就涉及到了数组的拷贝,其对性能的影响也很严重。

所以需要提前对可能的情况有良好的预测,才能真正发挥哈希表的优势。

转载于:https://www.cnblogs.com/yizhiamumu/p/9112725.html

源码:Java集合源码之:哈希表(二)相关推荐

  1. 精尽 JDK 源码解析 —— 集合(四)哈希表 LinkedHashMap

    1. 概述 众所周知,HashMap 提供的访问,是无序的.而在一些业务场景下,我们希望能够提供有序访问的 HashMap .那么此时,我们就有两种选择: TreeMap :按照 key 的顺序. L ...

  2. Java集合源码分析(二)ArrayList

    ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...

  3. JavaScript数据结构与算法(2)(集合、字典、哈希表、二叉树、图)(ES6)

    注意:原教学视频:JavaScript(ES6)数据结构和算法 | JavaScript数据结构与算法 (都是CoderWhy老师的教学) 原作者(笔记)链接:JavaScript 数据结构与算法 | ...

  4. Java集合源码学习(四)HashMap

    一.数组.链表和哈希表结构 数据结构中有数组和链表来实现对数据的存储,这两者有不同的应用场景, 数组的特点是:寻址容易,插入和删除困难:链表的特点是:寻址困难,插入和删除容易: 哈希表的实现结合了这两 ...

  5. 【Java集合源码剖析】Hashtable源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元 ...

  6. java地图源码_Java集合源码分析(四)HashMap

    一.HashMap简介 1.1.HashMap概述 HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对映射.此类不保证映射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作 ...

  7. java遍历范型list_Java 集合(1)-- 俯瞰 Java 集合源码以及分类

    (一) java集合分类 之前大概分为三种,Set,List,Map三种,JDK5之后,增加Queue.主要由Collection和Map两个接口衍生出来,同时Collection接口继承Iterab ...

  8. Java集合源码解析

    文章目录 1.集合包 1.1 ArrayList 实现方式 创建:ArrayList() 插入对象:add(E) 删除对象:remove(E) 获取单个对象:get(int) 遍历对象:iterato ...

  9. Java集合源码浅析(一) : ArrayList

    (尊重劳动成果,转载请注明出处:https://yangwenqiang.blog.csdn.net/article/details/105418475冷血之心的博客) 背景 一直都有这么一个打算,那 ...

  10. 【Java集合源码剖析】HashMap源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955 您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票,谢 ...

最新文章

  1. Oracle EBS R12 运行adadmin 安装中文语言包过程中意外中断后的处理
  2. 粘贴铜箔简易实验电路制作
  3. 数据库 1205 Error 'Lock wait timeout exceeded; try restarting transaction' on query
  4. 并发锁之二:ReentrantReadWriteLock读写锁
  5. 作业收缴系统设计手册(自写开源小系统)
  6. 装修行业难互联网化?利润不合理并非本质,体制才是
  7. Invalid bound statement (not found) 解决方案
  8. 安装elasticsearch-analysis-ik中文分词器
  9. shell脚本实例-判断主机存活 以及企业备份方案
  10. 通过修改注册表,实现网页链接中的私有协议启用本地exe进程
  11. 参考文献起止页码怎么写_毕业论文文献综述不会写?快来看看这篇文章(附含通用模板)...
  12. 前端三大框架Angular React Vue
  13. 【Python】解析Python中的条件语句和循环语句
  14. 服务器lsass状态代码c0000005,Windows服务器上lsass.exe进程CPU使用率异常问题排查方法...
  15. python出入库_Python-批量导出excel加盟商出入库明细
  16. 基于物联网的防盗报警器设计与实现
  17. python 自己选择excel保存的位置
  18. 销量惨淡,广告费ACOS飙升
  19. 百万调音师—Audition多轨编辑
  20. 微软官方制作纯净版的U盘启动盘(详细步骤)

热门文章

  1. 拓端tecdat|R语言基于ARMA-GARCH-VaR模型拟合和预测实证研究分析案例
  2. android pokemon go,安卓Pokemon GO懒人版
  3. c语言输入数字 获取星期几,输入字母,判断星期几,求大神指点
  4. java性能调试命令_性能测试--十个命令迅速发现性能问题
  5. Java事件处理机制的两个案例
  6. 有必要买吗_婴儿床有必要买吗 婴儿床有用吗
  7. 1、反转一个3位整数
  8. pytorch def __init__(self, num_classes, bkg_label, top_k, conf_thresh, nms_thresh):
  9. Pandas常用函数diff和shift函数学习使用
  10. 字典树-大量字符串前缀及出现次数是否存在统计(Trie树-java)算法实现