基于JDK1.8的HashMap分析】的更多相关文章

HashMap的强大功能,相信大家都了解一二.之前看过HashMap的源代码,都是基于JDK1.6的,并且知其然不知其所以然,现在趁着寒假有时间,温故而知新.文章大概有以下几个方面: HashMap的数据结构 put方法 get方法 (一)HashMap的底层数据结构 static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> nex…
作为一种最为常用的容器,同时也是效率比较高的容器,HashMap当之无愧.所以自己这次jdk源码学习,就从HashMap开始吧,当然水平有限,有不正确的地方,欢迎指正,促进共同学习进步,就是喜欢程序员这种开源精神.(好吧,第一篇博客有点紧张) 一. HashMap结构 HashMap在jdk1.6版本采用数组+链表的存储方式,但是到1.8版本时采用了数组+链表/红黑树的方式进行存储,有效的提高了查找时间,解决冲突.这里有一篇博客写的非常好,HashMap的结构图也画的非常清楚,鼎力推荐一下杭州M…
HashMap在开发中经常用,面试源码方面也会经常问到,在之前也多次了解过源码,今天算是复习一下,顺便好好总结一下,包括在后面有 相关面试题.本文不会对红黑树代码由太多深入研究,特别是删除方面太复杂,面试也不会问到,知道红黑树基本实现原理就可以了 源码基于jdk1.8,我们都知道1.8版本的HashMap有很大改变,通过数组+链表+红黑树实现 图例: 关于链表和红黑树相关内容,可以参考: Java数据结构和算法(四)--链表 Java数据结构和算法(八)--红黑树与2-3树 基本结构: publ…
之前看过ConcurrentHashMap的分析,感觉也了解的七七八八了.但昨晚接到了面试,让我把所知道的ConcurrentHashMap全部说出来. 然后我结结巴巴,然后应该毫无意外的话就G了,今天下定决心好好分析一下,这个万能的并发包,ConcurrentHashMap 分一下几个方面分析ConcurrentHashMap: put方法 remove方法 get方法 (一)put方法 public V put(K key, V value) { return putVal(key, val…
HashMap 源码分析  基于jdk1.8分析 1:数据结构: transient Node<K,V>[] table;  //这里维护了一个 Node的数组结构: 下面看看Node的数据结构,Node是它的一个内部类: static class Node<K,V> implements Map.Entry<K,V> { final int hash;  //hash值 final K key;    //key V value;      //value Node&…
[集合框架]JDK1.8源码分析之HashMap(一)   一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也可以使用红黑树进行存储,总之,目标只有一个,那就是在安全和功能性完备的情况下让其速度更快,提升性能.好~下面就开始分析源码. 二.HashMap数据结构 说明:上图很形象的展示了HashMap的数据结构(数组+链表+红黑树),桶中的结构可能…
这一篇是接着上一篇写的, 上一篇的地址是:基于JDK1.8版本的hashmap源码分析(一)     /**     * 返回boolean类型的值,当集合中包含key的键值,就返回true,否则就返回false:和get(key)方法调用的是同一个底层实现方法getNode()     */ public boolean containsKey(Object key) { return getNode(hash(key), key) != null; } /** *这个方法主要是实现在map中…
目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑树拆分 总结 心得 前言 今天我们来学习Java中较为常用的集合类 HashMap. 另外说明一下,本文的 HashMap 源码是基于Jdk1.8版本的,如果没有特别说明的话,之后的集合类源码解析都是1.8的版本. HashMap的数据结构 打开HashMap源码文件,可以看到它是继承自 Abstr…
容器源码分析 如果没有特别说明,以下源码分析基于 JDK 1.8. 在 IDEA 中 double shift 调出 Search EveryWhere,查找源码文件,找到之后就可以阅读源码. List ArrayList 1. 概览 实现了 RandomAccess 接口,因此支持随机访问.这是理所当然的,因为 ArrayList 是基于数组实现的. public class ArrayList<E> extends AbstractList<E> implements List…
这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JDK1.6.JDK1.7的.现在我来分析一哈最新的JDK1.8的HashMap及性能优化. 在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效…
1.前提 在阅读这篇博客之前,希望你对HashMap已经是有所理解的,否则可以参考这篇博客: jdk1.8源码分析-hashMap:另外你对java的cas操作也是有一定了解的,因为在这个类中大量使用到了cas相关的操作来保证线程安全的. 2.概述 ConcurrentHashMap这个类在java.lang.current包中,这个包中的类都是线程安全的.ConcurrentHashMap底层存储数据的结构与1.8的HashMap是一样的,都是数组+链表(或红黑树)的结构.在日常的开发中,我们…
在Java语言中使用的最多的数据结构大概右两种,第一种是数组,比如Array,ArrayList,第二种链表,比如ArrayLinkedList,基于数组的数据结构特点是查找速度很快,时间复杂度为 O(1),但是删除的速度比较慢,因为每次删除元素的时候需要把后面的所有的元素都要相应的往前移动一位,最坏的情况删除第一个元素,时间复杂度为O(n).基于链表实现的数据结构的特点是删除的速度比较快,但是查找的速度比较慢,每次查找数据的时候都需要从链表头部开始往下遍历,链表查找最坏时间是O(n).Hash…
死磕Java之聊聊HashMap源码(基于JDK1.8) http://cmsblogs.com/?p=4731 为什么面试要问hashmap 的原理…
HashMap实现详解 基于JDK1.8 1.数据结构 散列表:是一种根据关键码值(Key value)而直接进行访问的数据结构.采用链地址法处理冲突. HashMap采用Node<K,V>数组作为散列表来存储数据.源码声明如下: /** * The table, initialized on first use, and resized as * necessary. When allocated, length is always a power of two. * (We also to…
本篇分析ArrayList的源码,在分析之前先跟大家谈一谈数组.数组可能是我们最早接触到的数据结构之一,它是在内存中划分出一块连续的地址空间用来进行元素的存储,由于它直接操作内存,所以数组的性能要比集合类更好一些,这是使用数组的一大优势.但是我们知道数组存在致命的缺陷,就是在初始化时必须指定数组大小,并且在后续操作中不能再更改数组的大小.在实际情况中我们遇到更多的是一开始并不知道要存放多少元素,而是希望容器能够自动的扩展它自身的容量以便能够存放更多的元素.ArrayList就能够很好的满足这样的…
上篇我们分析了ArrayList的底层实现,知道了ArrayList底层是基于数组实现的,因此具有查找修改快而插入删除慢的特点.本篇介绍的LinkedList是List接口的另一种实现,它的底层是基于双向链表实现的,因此它具有插入删除快而查找修改慢的特点,此外,通过对双向链表的操作还可以实现队列和栈的功能.LinkedList的底层结构如下图所示. F表示头结点引用,L表示尾结点引用,链表的每个结点都有三个元素,分别是前继结点引用(P),结点元素的值(E),后继结点的引用(N).结点由内部类No…
JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同,或者hashcode取模后的结果相同(hash collision),那么这些key会被定位到Entry数组的同一个格子里,这些key会形成一个链表. 在hashcode特别差的情况下,比方说所有key的hashcode都相同,这个链表可能会很长,那么put/get操作都可能需要遍历这个链表 也就是说时间复杂度在最差情况下会退化到O(n) JDK1.8中 使…
一.前言 分析完了List的两个主要类之后,我们来分析Set接口下的类,HashSet和LinkedHashSet,其实,在分析完HashMap与LinkedHashMap之后,再来分析HashSet与LinkedHashSet,就会变成异常简单,下面开始进行分析. 二.数据结构 2.1 HashSet数据结构 老规矩,先上数据结构,因为HashSet底层是基于HashMap 或者 LinkedHashMap实现的,所以HashSet数据结构就是HashMap或者LinkedHashMap的数据…
一.前言 上篇已经分析了Set接口下HashSet,我们发现其操作都是基于hashMap的,接下来看LinkedHashSet,其底层实现都是基于linkedHashMap的. 二.linkedHashSet的数据结构 因为linkedHashSet的底层是基于linkedHashMap实现的,所以linkedHashSet的数据结构就是linkedHashMap的数据结构,因为前面已经分析过了linkedHashMap的数据结构,这里不再赘述.集合之LinkedHashMap(含JDK1.8源…
一.前言 我们已经分析了List接口下的ArrayList和LinkedList,以及Map接口下的HashMap.LinkedHashMap.TreeMap,接下来看的是Set接口下HashSet和LinkedHashSet,其实在分析完了HashMap.LinkedHashMap之后,再来看HashSet和LinkedHashSet就会非常简单. 四个关注点在hashSet上的答案 二.hashSet的数据结构 因为hashSet的底层是基于hashMap,所以hashSet的数据结构就是h…
HashSet的UML图 HashSet的成员变量及其含义 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { static final long serialVersionUID = -5024744406713321676L; // 底层使用HashMap来保存HashSet中所有元素. private transien…
一.数据结构 HashMap中的数据结构是数组+单链表的组合,以键值对(key-value)的形式存储元素的,通过put()和get()方法储存和获取对象. (方块表示Entry对象,横排表示数组table[],纵排表示哈希桶bucket[实际上是一个由Entry组成的链表,新加入的Entry放在链头,最先加入的放在链尾],) 二.实现原理 成员变量 源码分析: /** 初始容量,默认16 */ static final int DEFAULT_INITIAL_CAPACITY = 1 <<…
概述 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等.本文主要分析一下HashMap中红黑树树化的过程. 红黑树(red black tree) 一个节点标记为红色或者黑色. 根是黑色的. 如果一个节点是红色的,那么它的子节点必须是黑色的(这就是为什么叫红黑树). 一个节点到到一个null引用的每一条路径必须包含相…
JDK1.8中的HashMap实现跟JDK1.7中的实现有很大差别.下面分析JDK1.8中的实现,主要看put和get方法. 构造方法的时候并没有初始化,而是在第一次put的时候初始化 putVal方法的主要逻辑是这样的: 1.如果数组还没有初始化(数组长度是0),则先初始化 2.通过hash方法计算key的hash值,进而计算得到应该放置到数组的位置 3.如果该位置为空,则直接放置此处 4.如果该位置不为空,而且元素是红黑树,则插入到其中 5.如果是链表,则遍历链表,如果找到相等的元素则替换,…
前言 本文是基于JDK1.8的ArrayList进行分析的.本文大概从以下几个方面来分析ArrayList这个数据结构 构造方法 add方法 扩容 remove方法 (一)构造方法 /** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentExcept…
一.前言 前面分析了Set接口下的hashSet和linkedHashSet,下面接着来看treeSet,treeSet的底层实现是基于treeMap的. 四个关注点在treeSet上的答案 二.treeSet的数据结构 因为treeSet的底层是基于treeMap的,所以treeSet的数据结构就是treeMap的数据结构:红黑树,因为前面已经分析过了treeMap的数据结构,这里不再赘述.集合之TreeMap(含JDK1.8源码分析). 三.treeSet源码分析-属性及构造函数 3.1 类…
概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Condition:ReentrantLock的内部类Sync继承了AQS这个抽象类,Sync的newCondition()返回AQS的ConditionObject 关键:队列已经满时入队,将当前线程加入notFull这个Condition等待队列,唤醒等待notEmpty条件的线程. 关键:队列为空…
概要: ReentrantLock类内部总共存在Sync.NonfairSync.FairSync三个类,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQueuedSynchronizer抽象类 对ReentrantLock类的操作大部分都直接转化为对Sync和AbstractQueuedSynchronizer类的操作. 公平锁资源被其他线程占用且不是重入情况,该线程就会添加到同步队列的尾部,而不会先尝试获取资源. 非公平锁会尝试去获取资源,如果此…
LinkedList作为一种常用的List,是除了ArrayList之外最有用的List.其同样实现了List接口,但是除此之外它同样实现了Deque接口,而Deque是一个双端队列接口,其继承自Queue,所以LinkedList同样可以用来模拟队列,栈以及双端队列. 一.基本用法 因为LinkedList是基于链表实现的,所以注定其插入和删除操作速度要快于ArrayList,但是由于其是链表结构,所以其随机访问查找检索速度慢于基于数组的ArrayList. 这里先主要说一下LinkedLis…
序言:上一节说了阅读源码的顺序,有了一个大体的方向,咱们就知道该如何下手.接下来,就要搭建一个方便阅读源码及debug的环境.有助于跟踪源码的调用情况. 目前新开发的项目, 大多数都是基于JDK1.8开发,所以我选择该版本进行源码分析. JDK1.8版本号:jdk1.8.0_151 一. JDK1.8的src在哪里? 找到JDK安装包所在目录,会看到src.zip的压缩包,这里面就是JDK的源码,如下图. 二. idea搭建步骤 01. 新建一个简单的Java工程 打开idea,菜单栏File…