建议本文结合java源码来阅读,看了之后就什么都懂了,还有参考文献。

  • 散列(Hash) 是一种按关键字编址的存储和检索方法
  • 散列表(HashTable)根据元素的关键字确定元素的位置
  • 散列函数(Hash Function)建立数据元素的关键字到该元素的存储位置的一种映射关系
    (具体如何计算百度一下很简单,Hash算法的难处在如何确定散列函数和解决冲突)
常见的散列函数计算方法
  • 除留余数法
int hash(int key)
{return key%prime;
}

如果key的类型是T 要返回一个 int hashCode() 返回散列码,约定对象到int的一对一映射,每个对象的散列码必须不同

template<T>
int HashSet<T>::set(T key)
{return key.hashCode() %prime;
}

除留余数法的关键在于如何选取prime的值。通常选取小于散列表长度的最大素数。

  • 平方取中法 例如,k=4731,k2=22382361,若表长为100,取中间两位。hash(k)=82
  • 全域散列法:在所有的散列函数中随机的选取一个散列函数,以防止n个关键字全部散列到同一个槽中
处理冲突
  • 链地址法。将同义词冲突的元素存储在一条同义词单链表中。

下面来谈一下java中的hash集合

HashMap

取hashMap的方法
System.out.println("里面的键值对是:");
Set<Map.Entry<String, String>> set = map.entrySet();
Iterator<Map.Entry<String, String>> iterator2 = set.iterator();
while (iterator2.hasNext()) {  Map.Entry<String, String> entry = iterator2.next();  System.out.println("键是:" + entry.getKey() + "值是:" + entry.getValue());
}
谈谈你理解的 HashMap,讲讲其中的 get put 过程。
  • 是由数组加链表组成,
  • put过程会根据key的hashcode做hash,如果没碰撞直接放到桶里,如果碰撞了,则执行equals()函数判断key是否相等,如果相等进行覆盖,不相等,以链表的形式存放,如果长度于TREEIFY_THRESHOLD,就把链表转换成红黑树,桶满了要resize() 超过了load factor * current capacity
  • get 如果桶中只有一个节点则命中,如果有冲突则通过key.equals去查找要查找的值,有红黑树和链表两种。
1.8 做了什么优化?
  • 在1.8之前是用链表解决冲突的,1.8采用的红黑树解决冲突时间复杂度编程logn
你知道hash的实现吗?为什么要这样实现?
  • 在Java 1.8的实现中,是通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的,这么做可以在bucket的n比较小的时候,也能保证考虑到高低bit都参与到hash的计算中,同时不会有太大的开销。
是线程安全的嘛?
  • 不是线程安全的,线程安全的有HashTable和ConcurrentHashMap.
不安全会导致哪些问题?
  • 原子性,有序性,可见性
ConcurrentHashMap 是如何实现的? 1.7、1.8 实现有何不同?为什么这么做?

原理上来说:ConcurrentHashMap 采用了分段锁技术。不会像 HashTable 那样不管是 put 还是 get 操作都需要做同步处理,理论上 ConcurrentHashMap 支持 CurrencyLevel 的线程并发。jdk 1.7使用segment存放数据,segment继承了ReentrantLock充当锁的角色,为每一个segment提供了线程安全的保障,segment维护了哈希的若干个桶,每个桶由HashEntry构成链表。1.8舍弃了segment,大量使用了synchronized,以及CAS无锁操作以保证ConcurrentHashMap操作的线程安全性。至于为什么不用 ReentrantLock 而是 Synchronzied 呢?实际上,synchronzied 做了很多的优化,包括偏向锁,轻量级锁,重量级锁,可以依次向上升级锁状态,但不能降级,因此,使用 synchronized 相较于 ReentrantLock 的性能会持平甚至在某些情况更优。另外,底层数据结构改变为采用数组+链表+红黑树的数据形式。

HashTable和HashMap的区别
  • HashMap不是线程安全的,但是效率较高,HashTable是线程安全的但是效率较低,因为put和get的操作都加上了同步锁,解决这个问题就是用ConcurrentHashMap
HashTable和ConcurrentHashMap的区别
  • HashTable的put和get操作都用到了同步锁是一种悲观锁效率比较低。
  • ConcurrentHashMap用的是同步锁加CAS无锁操作,通过加transient关键字来实现。
  • put操作。
    • 如果没有初始化就先调用initTable()方法来进行初始化过程
    • 如果没有hash冲突就直接CAS插入
    • 如果还在进行扩容操作就先进行扩容如果存在hash冲突,就加锁来保证线程安全,这里有两种情况,一种是链表形式就直接遍历到尾端插入,一种是红黑树就按照红黑树结构插入,最后一个如果该链表的数量大于阈值8,就要先转换成黑红树的结构,break再一次进入循环如果添加成功就调用addCount()方法统计size,并且检查是否需要扩容
  • get操作
    • 计算hash值,定位到该table索引位置,如果是首节点符合就返回
    • 如果遇到扩容的时候,会调用标志正在扩容节点ForwardingNode的find方 法,查找该节点,匹配就返回
    • 以上都不符合的话,就往下遍历节点,匹配就返回,否则最后就返回null

HashSet

  • HashSet是基于HashMap来实现的,操作很简单,更像是对HashMap做了一次“封装”,而且只使用了HashMap的key来实现各种特性。

LinkedHashMap和LinkedHashSet

  • LinkedHashSet就是继承了HashSet维护一个双链表和LinkedHashMap一样。、
  • LinkedHashMap 是 HashMap 的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用 LinkedHashMap。

参考文献

1.java源码
2.《数据结构(C++版)》 叶核亚编著
3.ConcurrentHashMap
4.Java并发编程:volatile关键字解析
5.java HashMap工作原理及实现
6.java中Cloneable和Serializable接口详情
7.Java transient关键字使用小记
8.无锁算法——CAS原理
9.HashTable,ConcurrentHashMap
10.LinkedHashMap

聊聊传说中的散列哈希Hash算法,以及Java中的HashTable,HashMap,HashSet,ConcurrentHashMap......相关推荐

  1. 散列(哈希 hash)

    目录 前言 hash介绍 字符串hash初步 练习题 前言 散列(hash)是常用的算法之一. 为了了解hash我们先看一个简单的题. 题目: 给出N个正整数,再给出M个正整数,问这M个数中的每个数分 ...

  2. Java 国密算法 SM3 散列哈希使用

    Java 国密算法 SM3 散列哈希使用 文章目录 Java 国密算法 SM3 散列哈希使用 引入依赖 计算散列哈希 引入依赖 <dependency><groupId>org ...

  3. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  4. 一致性Hash算法(JAVA版)(摘抄至五月的仓颉的博客)

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  5. 生成FaceBook所需的散列哈希值

    Hex to base64 converter FaceBook后台发布应用时,需要填入hash值,今天自己用openssl生成的时候只有24位并不正确,与其费劲巴拉的自己折腾openssl,还是感谢 ...

  6. 常见的哈希Hash算法 MD5 对称非对称加密 海明码

    2019独角兽企业重金招聘Python工程师标准>>> 参考 Link 另外,这篇文章也提到了利用Hash碰撞而产生DOS攻击的案例: http://www.cnblogs.com/ ...

  7. 【IoT】加密与安全:哈希 Hash 算法用途与原理解析

    1.Hash 算法分类 MD5 和 SHA-1 是目前应用最广泛的 Hash 算法且是以 MD4 算法为基础设计的. 1) MD4 MD4(RFC 1320) 是 MIT 的 Ronald L. Ri ...

  8. hash的算法 java_【数据结构与算法】一致性Hash算法及Java实践

    追求极致才能突破极限 一.案例背景 1.1 系统简介 首先看一下系统架构,方便解释: 页面给用户展示的功能就是,可以查看任何一台机器的某些属性(以下简称系统信息). 消息流程是,页面发起请求查看指定机 ...

  9. 一致性Hash算法及Java实践

    目录 一.案例背景 1.1 系统简介 1.2 遇到问题 1.3 初步优化 1.4 继续优化 二.使用一致性Hash解决问题 三.一致性Hash介绍 3.1 理论简介 3.2 设计实现 四.对一致性Ha ...

最新文章

  1. 智能写作全景介绍:从最新前沿技术到行业落地解析
  2. CDC,CPaintDC,CClientDC,CWindowDC区别
  3. 浏览器兼容性导致网址显示不完整
  4. mysql数据库子查询的使用_MySQL数据库使用子查询方式更新数据优化及思考
  5. python各种类型转换-int,str,char,float,ord,hex,oct等
  6. DevOps vs. Agile:它们有什么共同点?
  7. php mysql设计中验证码的实现_php如何实现验证码功能
  8. ThinkPHP admin.php后台登录
  9. WEB应用中的信息泄漏以及攻击方法
  10. CCF201503-5 最小花费(100分解题链接)
  11. Winform 中 dataGridView 导出到Excel中的方法总结
  12. C#DataGridView中的常用技巧
  13. linux exec操作文件描述符
  14. “酸碱体质理论”是个骗局
  15. 小米安装linux驱动怎么安装教程,小米手机驱动程序怎么安装教程【图文版】
  16. win32com在wps上另存为SaveAs报错
  17. java 百度经纬度 转换为 高德经纬度 谷歌
  18. matlab中的矩阵求和
  19. 阿里玄难:面向不确定性的软件设计几点思考
  20. 网络精英赛模拟练习(4)

热门文章

  1. 基类Object的子类有哪些以及字符串和数组的方法
  2. okhttp初识拦截器
  3. windows下PostgreSQL 安装与配置
  4. 插入排序,二分查找插入排序,使用二叉树的插入排序
  5. HTML解决div里面img的缝隙问题
  6. NO.4 Android开发中常用框架及工具
  7. mngoDB 常用语法
  8. 鼠标指向表格时 显示更多信息 toolTipController1
  9. 【转】Treeview 无限分类非递归终极解决方案
  10. 小程序入门学习20--springboot之集成mybatis