treeify

Java核心——集合

夙愿已清 提交于 2020-11-29 00:44:19
参考 https://blog.csdn.net/stanwuc/article/details/81509083 https://www.cnblogs.com/javabg/p/7258550.html https://blog.csdn.net/yinbingqiu/article/details/60965080 https://www.imooc.com/article/71730?block_id=tuijian_wz //源码解析 https://blog.csdn.net/xuefeng0707/article/details/40797085 //扩容死锁 Java集合家族图解 https://img-blog.csdn.net/20160124221843905 整体特征 接口 子接口 是否有序 是否允许元素重复 Set 无序不可重复 AbstractSet 否 否    HashSet(基于HashMap) 否 否    TreeSet 是(用二叉排序树) 否 List   无序可重复 ArrayList 有 是        LinkedList 有 是        Vector 有 是 Map AbstractMap 否 使用key-value来映射和存储数据,key必须唯一,value可以重复    HashMap 否    TreeMap 是

Java 集合类Hashmap

我是研究僧i 提交于 2020-11-24 19:53:11
一.HashMap 简介 HashMap在程序员的开发过程中是一个十分常用的集合类,它是一个以键值对形式存在的集合类, 在开发中我们可以利用的它的一个key存在即替换的特性,实现一个更新的去重的操作。 在另一个方便我们可以利用map跟fastJson快速组成我们所需的json数据格式。 在jdk1.8之前,HashMap是以数组+链表的形式存在,put进来的key的hashCode进过扰动函数计算后得到hash值,然后该值通过(n-1)&hash计算后的到相应的位置(n代表的是数组长度), 如果发生了hash冲突,则先判断该key是否存在,如果存在那么就覆盖,否则以“拉链法”解决冲突,便组成了链表。 但在jdk1.8之后,HashMap就发生了改变,如果当前链表的长度大于阈值(默认是8)那么该链表就转换成红黑树,加快了搜索速度。 二.HashMap属性 //HashMap的默认初始容量 2^4=16 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 //HashMap的最大容量 static final int MAXIMUM_CAPACITY = 1 << 30; //默认的装载因子当数组长度 static final float DEFAULT_LOAD_FACTOR = 0.75f; // 当桶

jdk1.8 HashMap底层数据结构:散列表+链表+红黑树(图解+源码)

别说谁变了你拦得住时间么 提交于 2020-11-23 23:49:40
一、前言   本文由jdk1.8源码整理而得,附自制jdk1.8底层数据结构图,并截取部分源码加以说明结构关系。 二、 jdk1.8 HashMap底层数据结构图    三、源码    1.散列表(Hash table,也叫哈希表): /** * 表,第一次使用时初始化(而非实例化集合时进行初始化),并根据需要调整大小。 当分配时,长度总是2的幂。 (在某些操作中,我们还允许长度为零,以允许当前不需要的引导机制。)    */ transient Node<K,V>[] table;    2.链表: /** * Basic hash bin node, used for most entries. (See below for * TreeNode subclass, and in LinkedHashMap for its Entry subclass.) */ static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node <K,V> next;      …… }    3.红黑 树: /** * Entry for Tree bins. Extends LinkedHashMap.Entry (which in turn * extends Node

HashMap源码实现分析

杀马特。学长 韩版系。学妹 提交于 2020-10-15 20:58:14
HashMap源码实现分析 一、前言 HashMap 顾名思义,就是用hash表的原理实现的Map接口容器对象,那什么又是hash表呢。 我们对数组都很熟悉,数组是一个占用连续内存的数据结构,学过C的朋友对这一点影响肯定更为深刻。既然是一段连续的内存,数组的特点就显而易见了,一旦你知道要查第几个数据,时间复杂度就是O(1),但是对于插入操作就很困难;还有一种数据结构你也一定很熟悉,那就是链表,链表由一组指向(单向或者双向)的节点连接的数据结构,它的特点是内存不连续,查找困难,但是插入删除都很容易。 那有没有一种查找容易,插入删除查找都容易的数据结构呢, 没错,它就是hash表。 本篇,我们就来讨论: HashMap的数据结构实现方式 HashMap是怎么做到为get、put操作提供稳定的时间复杂度的 HashMap什么时候从单节点转成链表又是什么时候从链表转成红黑树 HashMap初始化时为什么要给自定义的初始容量。 HashMap如何保证容量始终是2的幂 HashMap为何要保证容量始终是2的幂 HashMap的hash值如何计算 HashMap为什么是线程不安全的 要了解HashMap 最好的方式就是看源码,本篇内容基于Jdk1.8HashMap源码。 二、HashMap的基本要素 磨刀不误砍柴功,想了解HashMap的原理,必然绕不过HashMap源码中的以下几个变量:

HashMap 源码分析

荒凉一梦 提交于 2020-08-18 05:40:32
  --翻开 HashMap 的源码,首先看到的就是 Doug Lea 大爷的大名。每当看到这个名字,就像看到小胡子大爷和蔼的对我们说“少年,你渴望力量吗”。   这次不以面试背题为目的,挑几个源码实现中值得玩味的点来学习一下。   首先看几个初始化参数,在实现中 Lea 大爷大量的使用了二进制位移运算。比如 16 表示为 1<<4 ,1 073 741 824 表示为 1<<30 。由于计算机的物理特性,二进制运算的效率尤其是位移运算是高于直接使用十进制运算的。在非官方统计中,位运算比取余运算可以节约大约四十余个 CPU 晶振周期,按照Bruce Eckel给出的数据,性能大约可以提升5~8倍。在日常 CURD 的过程中,也可以在写好注释的前提下尽量的使用二进制位运算替代十进制运算。 负载因子(LOAD_FACTOR)   初始容量为 16,负载因子为 0.75。这是从 HashMap 诞生开始就没变过的定义,当元素数量达到当前容量的 75% 时,HashMap 会对数组进行扩容。该因子可在创建实例时指定。   由于哈希值在计算时需要映射到长度为 capacity 的数组下标上,因此哈希值的计算必然包含对数组长度的取模(取模的点后面说),在 put 方法中可以找到计算数组下标时需要对数组长度取模:   因此数组的剩余空间越小,数组下标冲突的几率越大,元素不得不存储在链表中

HashMap在JDK8中的源码分析

↘锁芯ラ 提交于 2020-08-10 22:04:39
map.put(key1,value1); 首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。 如果此位置上的数据为空,此时的key1-value1添加成功。 ----情况1 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据 的哈希值: 如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。----情况2 如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals(key2)方法,比较: 如果equals()返回false:此时key1-value1添加成功。----情况3 如果equals()返回true:使用value1替换value2。 补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储。 在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。 jdk8 相较于jdk7在底层实现方面的不同: 1. new HashMap():底层没有创建一个长度为16的数组 2. jdk 8底层的数组是:Node[]

HashMap源码分析(基于JDK1.8版本)

我的未来我决定 提交于 2020-08-08 08:36:14
HashMap源码分析(基于JDK1.8版本) 简介 1 注解内容 1.1 结构性修改(Structurally modification) 1.2 fail-fast机制 2 主要成员 2.1 主要静态变量 2.2 主要的类 2.3 field 3 主要方法介绍与代码剖析 3.1 hash() 3.2 tableSizeFor() 3.3 get() 3.4 put() 3.5 resize() 4 jdk1.8中的HashMap相对于1.7的优化 4.1 hash函数发生了变化 4.2 数组+链表改成了数组加链表或者红黑树 4.3 链表插入的方法从头插法改成了尾插法 4.4 扩容时的分配位置的判断 4.5 先插入再扩容 5 HashMap存在的一些问题 5.1 并发的情况下会不会导致死循环? 简介 作为一个Java语言的使用者,HashMap是一个绕不开的话题。这段时间我准备完整的学习一遍HashMap的源码并将自己的收获记录一下。这是我记录的第一篇Java源码分析,有疏漏或者错误之处欢迎大家批评指正。 1 注解内容 HashMap前面的注解内容大概一百来行,逐行翻译的事情就没必要做了,在这里简单的对这一部分内容进行一个归纳,并记录下一些我觉得值得讨论的地方。 1.1 结构性修改(Structurally modification) 源码中有一段注解内容是:

HashMap初步解析

*爱你&永不变心* 提交于 2020-08-08 05:06:58
参考 美团技术团队-Java 8系列之重新认识HashMap 一些Map的比较 HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。 Hashtable:Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,并且是线程安全的,任一时间只有一个线程能写Hashtable,并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。 LinkedHashMap:LinkedHashMap是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的

深入理解HashMap和TreeMap的区别

十年热恋 提交于 2020-05-02 08:59:36
深入理解HashMap和TreeMap的区别 简介 HashMap和TreeMap是Map家族中非常常用的两个类,两个类在使用上和本质上有什么区别呢?本文将从这两个方面进行深入的探讨,希望能揭露其本质。 HashMap和TreeMap本质区别 先看HashMap的定义: public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable 再看TreeMap的定义: public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable 从类的定义来看,HashMap和TreeMap都继承自AbstractMap,不同的是HashMap实现的是Map接口,而TreeMap实现的是NavigableMap接口。NavigableMap是SortedMap的一种,实现了对Map中key的排序。 这样两者的第一个区别就出来了,TreeMap是排序的而HashMap不是。 再看看HashMap和TreeMap的构造函数的区别。 public HashMap(int initialCapacity, float

Java底层类和源码分析系列-ConcurrentHashMap源码分析

会有一股神秘感。 提交于 2020-04-17 17:52:34
要点 ConcurrentHashMap是HashMap的线程安全版本; 不允许[key,value]为null; 比Hashtable锁粒度更细; 采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树; 负载因子0.75; 默认初始化容量16; put时当前bucket为空时,使用CAS操作,将Node放入对应的bucket中; put时出现hash冲突,则采用synchronized; 查询操作不加锁,因此ConcurrentHashMap不是强一致性; ConcurrentHashMap内部采用的锁有synchronized、CAS、自旋锁、分段锁、volatile; 定义 public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>    implements ConcurrentMap<K,V>, Serializable 其中接口ConcurrentMap<K, V>来自Map<K, V>,添加了一些函数式接口方法,比如: default void forEach(BiConsumer<? super K, ? super V> action) default void replaceAll(BiFunction<? super K, ?