hashmap原理

Map的底层实现原理

走远了吗. 提交于 2020-01-08 09:58:28
一,前言 1.1,概述 ​ 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射(K-V)。Java提供了专门的集合类用来存放这种对象关系的对象,即 java.util.Map 接口。 Collection 中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。 Map 中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键(K)可以找对所对应的值(V)。 Collection 中的集合称为单列集合, Map 中的集合称为双列集合。 需要注意的是, Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。 ​ 通过查看Map接口描述,看到Map有多个子类,这里我们主要讲解常用的HashMap集合、LinkedHashMap集合。 HashMap<K,V> :存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。 LinkedHashMap<K,V> :HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法

分析HashMap性能卓越的原因

醉酒当歌 提交于 2019-12-17 04:38:09
hashcode概念 所有的对象,都有一个对应的hashcode(散列值) 比如字符串“gareen”对应的是1001 (实际上不是,这里是方便理解,假设的值) 比如字符串“temoo”对应的是1004 比如字符串“db”对应的是1008 比如字符串“annie”对应的也是1008 保存数据 准备一个数组,其长度是2000,并且设定特殊的hashcode算法,使得所有字符串对应的hashcode,都会落在0-1999之间 要存放名字是"gareen"的英雄,就把该英雄和名称组成一个键值对,存放在数组的1001这个位置上 要存放名字是"temoo"的英雄,就把该英雄存放在数组的1004这个位置上 要存放名字是"db"的英雄,就把该英雄存放在数组的1008这个位置上 要存放名字是"annie"的英雄,然而 "annie"的hashcode 1008对应的位置已经有db英雄了,那么就在这里创建一个链表,接在db英雄后面存放annie 查找数据 比如要查找gareen,首先计算"gareen"的hashcode是1001,根据1001这个下标,到数组中进行定位,(根据数组下标进行定位,是非常快速的) 发现1001这个位置就只有一个英雄,那么该英雄就是gareen. 比如要查找annie,首先计算"annie"的hashcode是1008,根据1008这个下标,到数组中进行定位

【集合系列】- 深入浅出分析HashMap

风格不统一 提交于 2019-12-16 22:30:37
一、摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties等等。 关于HashMap,一直都是一个非常热门的话题,只要你出去面试,我保证一定少不了它! 本文主要结合JDK1.7和JDK1.8的区别,就HashMap的数据结构和实现功能,进行深入探讨,废话也不多说了,直奔主题! 二、简介 在程序编程的时候,HashMap是一个使用非常频繁的容器类,它允许键值都放入null元素。除该类方法未实现同步外,其余跟Hashtable大致相同,但跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个HashMap的顺序可能会不同。 HashMap容器,实质还是一个哈希数组结构,但是在元素插入的时候,存在发生hash冲突的可能性; 对于发生Hash冲突的情况,冲突有两种实现方式, 一种开放地址方式(当发生hash冲突时,就继续以此继续寻找,直到找到没有冲突的hash值),另一种是拉链方式(将冲突的元素放入链表) 。 Java HashMap采用的就是第二种方式,拉链法。 在jdk1.7中,HashMap主要是由数组+链表组成,当发生hash冲突的时候

【集合系列】- 深入浅出分析HashMap

坚强是说给别人听的谎言 提交于 2019-12-06 16:27:29
一、摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties等等。 关于HashMap,一直都是一个非常热门的话题,只要你出去面试,我保证一定少不了它! 本文主要结合JDK1.7和JDK1.8的区别,就HashMap的数据结构和实现功能,进行深入探讨,废话也不多说了,直奔主题! 二、简介 在程序编程的时候,HashMap是一个使用非常频繁的容器类,它允许键值都放入null元素。除该类方法未实现同步外,其余跟Hashtable大致相同,但跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个HashMap的顺序可能会不同。 HashMap容器,实质还是一个哈希数组结构,但是在元素插入的时候,存在发生hash冲突的可能性; 对于发生Hash冲突的情况,冲突有两种实现方式, 一种开放地址方式(当发生hash冲突时,就继续以此继续寻找,直到找到没有冲突的hash值),另一种是拉链方式(将冲突的元素放入链表) 。 Java HashMap采用的就是第二种方式,拉链法。 在jdk1.7中,HashMap主要是由数组+链表组成,当发生hash冲突的时候

Day02

眉间皱痕 提交于 2019-12-06 09:35:02
数组 数组的拷贝 /** * 删除数组中指定索引位置的元素,本质上还是数组的拷贝 * * @param s * @param index * @return */ public static String[] removeElement(String[] s, int index) { System.arraycopy(s, index + 1, s, index, s.length - index - 1); s[s.length - 1] = null; return s; } /** * 数组扩容,本质上是定义一个更大的数组,然后将原数组内容拷贝到新数组中 * * @param s * @param num * @return */ public static String[] extendRange(String s, int num) { String[] s1 = new String[s.length() + num]; System.arraycopy(s, 0, s1, 0, s.length()); return s1; } java.util.Arrays Array.toString() //打印数组 Array.binarySearch() //二分法查找数组元素 多维数组 冒泡排序 /** * 冒泡排序法 * * @param a * @return *

【集合系列】- 深入浅出分析HashMap

痞子三分冷 提交于 2019-12-06 02:36:43
一、摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties等等。 关于HashMap,一直都是一个非常热门的话题,只要你出去面试,我保证一定少不了它! 本文主要结合JDK1.7和JDK1.8的区别,就HashMap的数据结构和实现功能,进行深入探讨,废话也不多说了,直奔主题! 二、简介 在程序编程的时候,HashMap是一个使用非常频繁的容器类,它允许键值都放入null元素。除该类方法未实现同步外,其余跟Hashtable大致相同,但跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个HashMap的顺序可能会不同。 HashMap容器,实质还是一个哈希数组结构,但是在元素插入的时候,存在发生hash冲突的可能性; 对于发生Hash冲突的情况,冲突有两种实现方式, 一种开放地址方式(当发生hash冲突时,就继续以此继续寻找,直到找到没有冲突的hash值),另一种是拉链方式(将冲突的元素放入链表) 。 Java HashMap采用的就是第二种方式,拉链法。 在jdk1.7中,HashMap主要是由数组+链表组成,当发生hash冲突的时候

.Net 中HashTable,HashMap 和 Dictionary<key,value> 和List<T>和DataTable的比较

一笑奈何 提交于 2019-12-05 20:15:26
.Net 中HashTable,HashMap 和 Dictionary<key,value> 和List 和DataTable的比较 转载自http://www.cnblogs.com/jilodream/p/4219840.html (一)HashTable 和Dic 数据结构 Hashtable和Dictionary从数据结构上来说都属于Hashtable(哈希表),都是对关键字(键值)进行散列操作,将关键字散列到Hashtable的某一个槽位中去,不同的是处理碰撞的方法。散列函数有可能将不同的关键字散列到Hashtable中的同一个槽中去,这个时候我们称发生了碰撞,为了将数据插入进去,我们需要另外的方法来解决这个问题。 采用链表法的是Dic 而采用开放寻址法(open addressing)-中 双重散列的方法的是 HashTable 至于这两种数据结构的使用方法 请自行阅读算法导论 或者参照网上博客 但从底层的数据结构可以发现 如果增删的动作很多的话 推荐使用Dic 因为解决碰撞的方式 是List.Add 如果改动的动作很少 查询的动作很多的话 则推荐 使用HashTable 因为映射查找之后 只需要跳跃查找到 碰撞后移动数据即可,另外当增加数据太多时,开放寻址的扩容很耗费性能(请阅读<算法导论>) Dic 和HashTable使用比较 1:单线程程序中推荐使用

HashMap源码学习

北慕城南 提交于 2019-12-05 02:17:47
常用方法 put 方法 描述: 最常用的方法之一,用来向hash桶中 添加 键值对 .但是这个方法并不会去执行实际操作.而是委托 putVal 方法进行处理 代码: public V put(K key, V value) { // 这次个调用分别指定了hash,key,value,替换现有值,非创建模式 return putVal(hash(key), key, value, false, true); } 这里调用了 hash 方法获取了 key 的 hash ,后面单独说这个 hash 的意义 putVal 方法 描述: 实际执行 put 操作的方法. 代码: final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { // tab - 当前hash桶的引用 // p - key所代表的节点(此节点不一定是目标节点,而仅仅是hash与桶长度的计算值相同而已)(它不为空时可能是链表或红黑树) // n - 当前桶的容量 // i - key在桶中的下标(同p,不代表目标节点) Node<K,V>[] tab; Node<K,V> p; int n, i; // 初始化局部变量tab并判断是否为空,初始化局部变量n并判断是否为0 // PS: 源码中大量的使用了这种书写方法

JAVA--高级基础开发

匆匆过客 提交于 2019-12-04 14:25:54
Day13[Map集合练习题] 练习一:Map接口的特点 请简述Map 的特点: Map集合中存放的数据都是键值对,并且键不能相同,值可以相同。 Map集合中的Key是根据Set集合来存放的。 Map集合可以使用null 作为键和值。 Map集合在输出顺序时,不保证顺序。 练习二:Entry键值对对象 说出Entry键值对对象遍历Map集合的原理。 答:Entry的原理:即通过集合中每个键值对(Entry)对象,获取键值对对象中的键与Map集合中存放是两种对象:一种是键,一种是值,它们在 Map 中是一一对应的,这一对对象又称作 Map 中的一个 Entry(项).Entry 将键值对的关系封装成了对象,即键值对对象。 练习题三: 3请使用Map集合的方法完成添加元素,根据键删除,以及根据键获取值操作 Map<String,String>map=new HashMap<>(); map.put("a","liwenjie"); map.put("b","sangfengjiao"); map.put("c","wangzhiya"); map.put("d","mashitian"); System.out.println(map.remove("a")); System.out.println(map.get("a")); 4练习四:Map接口中的方法 四

Java开发常见基础题大全

℡╲_俬逩灬. 提交于 2019-12-04 11:30:59
1.& 和 && 的区别? & :逻辑与( and ) , 运算符两边的表达式均为 true 时,整个结果才为 true 。 && :短路与,如果第一个表达式为 false 时,第二个表达式就不会计算了。 2. ” == ”和 equals 方法究竟有什么区别? == :表示两个变量的值是否相等,用于比较两个基本数据类型的数据或者引用变量。 equals: 用于比较两个独立对象的内容是否相同。字符串的比较也用 equals 。 == 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String 、 Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。 3. 比较字符串相等时用 equals 和 == 的区别 String 是对象,如果用 == 号就是比较两个 String 对象内存地址是否一样, equals() 比较的是 String 内容时候一样,不过不同的编程语言两者不太一样 4.Int 和 integer 的区别? Int 是 Java 的 8 中基本数据类型之一, integer 是 int 的封装类。 Int 类型的默认值为 0 , integer 默认值为 null ,所以区别在于, integer 能区分出 null 值和 0 的区别。 5