LinkedHashMap中有一个重要的数据: // LinkedEntry就是一个双向链表。 next); this.nxt = nxt; this.prv = prv; } } 接下来看源代码: public class LinkedHashMap header; e.prv = oldTail; oldTail.nxt = header.prv = e; modCount++; } } LinkedHashMap 如果是按照读取顺序来排序的,那么还要将这个节点放到双向链表的最后一位(这个特性,可以实现LRU算法) 参考: http://wiki.jikexueyuan.com/project/java-collection/linkedhashmap.html
LinkedHashMap学习 关系图 双向链表 static class Entry<K,V> extends HashMap.Node<K,V> { //after、before , V value, Node<K,V> next) { super(hash, key, value, next); } } 构造方法 public LinkedHashMap (int initialCapacity) { super(initialCapacity); accessOrder = false; } public LinkedHashMap () { super(); accessOrder = false; } public LinkedHashMap(Map<? putMapEntries(m, false); } /* *一般用此构造方法,accessOrder用来指定是否按顺序访问,如果为true就是按顺序访问,false根据新增排序 */ public LinkedHashMap
LinkedHashMap概述: LinkedHashMap是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。 LinkedHashMap的实现: 对于LinkedHashMap而言,它继承与HashMap、底层使用哈希表与双向链表来保存所有元素。 下面我们来分析LinkedHashMap的源代码: 类结构: public class LinkedHashMap<K, V> extends HashMap<K, V> implements Map< <K,V> lm = (LinkedHashMap<K,V>)m; // 如果定义了LinkedHashMap的迭代顺序为访问顺序, // 则删除以前位置上的元素,并将最新访问的元素添加到链表表头 如果你想构造一个LinkedHashMap,并打算按从近期访问最少到近期访问最多的顺序(即访问顺序)来保存元素,那么请使用下面的构造方法构造LinkedHashMap: public LinkedHashMap
accessOrder的解释 代码演示 @Test public void fun2() throws Exception { LinkedHashMap<String, String> accessOrderTrue = new LinkedHashMap<>(16, 0.75f, true); accessOrderTrue.put("1","1")
那么,LinkedHashMap 是怎样建立链表的呢? p;}// LinkedHashMap 中实现privatevoid linkNodeLast(LinkedHashMap.Entry<K,V> p){LinkedHashMap.Entry<K,V> 双向链表建立之后,我们就可以按照插入顺序去遍历 LinkedHashMap,大家可以自己写点测试代码验证一下插入顺序。 以上就是 LinkedHashMap 维护插入顺序的相关分析。 3.4 基于 LinkedHashMap 实现缓存 前面介绍了 LinkedHashMap 是如何维护插入和访问顺序的,大家对 LinkedHashMap 的原理应该有了一定的认识。 总结 本文从 LinkedHashMap 维护双向链表的角度对 LinkedHashMap 的源码进行了分析,并在文章的结尾基于 LinkedHashMap 实现了一个简单的 Cache。
LinkedHashMap 源码分析 1. 继承 继承的是 HashMap 这个就比较熟悉了,事实上我们会看到 LinkedHashMap 代码量非常的少,主要就是因为他继承的 HashMap ,继承了大多数的操作。 // 双向链表的头结点 transient LinkedHashMap.Entry<K,V> head; // 双向链表的尾节点 transient LinkedHashMap.Entry<K,V> tail Entry 节点 可能看过前面关于 HashMap 源码分析的都清楚,里面有一个 TreeNode 节点,他继承的就是 LinkedHashMap 中的 Entry 节点。 = e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before
LinkedHashMap维护插入的顺序。 LinkedHashMap实例,可自己指定初始容量,负载因子和排序模式. 构造一个维护插入顺序的LinkedHashMap实例,该实例具有与指定map相同的映射关系,创建的LinkedHashMap实例具有默认的加载因子(0.75)和足以容纳指定map中映射的初始容量. 下面一起看下 LinkedHashMap 插入相关代码. 5 链表节点的删除 HashMap 中保存的允许 LinkedHashMap 后处理的回调 与插入操作一样,LinkedHashMap 删除操作相关的代码也是直接用父类的实现.
转载请以链接形式标明出处: 本文出自:103style的博客 base on jdk_1.8.0_77 目录 LinkedHashMap简介 LinkedHashMap的全局变量介绍 LinkedHashMap 的构造函数 LinkedHashMap重写的函数 小结 参考文章 ---- LinkedHashMap简介 HashMap 是无序的,HashMap 在 put 的时候是根据 key 的 hashcode class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> LinkedHashMap 是 HashMap 的子类。 它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用 LinkedHashMap。 LinkedHashMap 是 Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。 LinkedHashMap 实现与 HashMap 的不同之处在于,LinkedHashMap 维护着一个运行于所有条目的 双重链接列表。
因此 JDK 推出一个基于 HashMap 但具有顺序的 LinkedHashMap 来解决有排序需求的场景。 它的底层是继承于 HashMap 实现的,由一个双向链表所构成。 LinkedHashMap 的排序方式有两种: 根据写入顺序排序。 根据访问顺序排序。 构造方法 LinkedHashMap 的构造方法: public LinkedHashMap() { super(); accessOrder = false; > m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; if (lm.accessOrder) { 因为是继承与 HashMap 的,所以一些 HashMap 存在的问题 LinkedHashMap 也会存在,比如不支持并发等。
; LinkedHashMap继承自HashMap,所以内部存储数据的方式和HashMap一样,使用数组加链表(红黑树)的结构存储数据,LinkedHashMap和HashMap相比,额外的维护了一个双向链表 这个双向链表的类型为LinkedHashMap.Entry。 = false; } public LinkedHashMap() { super(); accessOrder = false; } public LinkedHashMap(Map 那么,LinkedHashMap 是怎样建立链表的呢? 简单使用 我们先通过例子感受下LinkedHashMap的特性: LinkedHashMap<String, Object> map = new LinkedHashMap<>(16, 0.75f, false
因此 JDK 推出一个基于 HashMap 但具有顺序的 LinkedHashMap 来解决有排序需求的场景。 它的底层是继承于 HashMap 实现的,由一个双向链表所构成。 LinkedHashMap 的排序方式有两种: 根据写入顺序排序。 根据访问顺序排序。 构造方法 LinkedHashMap 的构造方法: public LinkedHashMap() { super(); accessOrder = false; <K,V> m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; if (lm.accessOrder) 因为是继承与 HashMap 的,所以一些 HashMap 存在的问题 LinkedHashMap 也会存在,比如不支持并发等。
而LinkedHashMap继承于HashMap,也是一个有序的Map,这似乎违背了Hash的理论。 (注:TreeMap和LinkedHashMap的有序性是不一样的,TreeMap的根据Key的大小来排序的,而LinkedHashMap是根据put的先后顺序来排序的) 我们来看这么一个例子 public LinkedHashMap.Entry<K,V> tail; 由于继承于HashMap,LinkedHashMap没有重写put()方法 在HashMap中 public V put(K key, V = e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a 重写了该方法 在LinkedHashMap中 void afterNodeRemoval(Node<K,V> e) { //将移除的节点从双向链表中断开 LinkedHashMap.Entry<
---- 1 前言 LinkedHashMap继承于HashMap,如果对HashMap原理还不清楚的同学,请先看上一篇:图解HashMap原理 2 LinkedHashMap使用与实现 先来一张LinkedHashMap 同样的数据,我们再试试LinkedHashMap Map<String, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("name" 先看看LinkedHashMap取遍历方式获取数据的代码: Map<String, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("name1", "josan1"); linkedHashMap.put("name2", "josan2"); linkedHashMap.put
JAVA 在 JDK1.4 以后提供了 LinkedHashMap 来帮助我们实现了有序的 HashMap! LinkedHashMap可以有两种保存的顺序:插入顺序及访问顺序. 在如下的代码中,我们以1,2,4,3的顺序分别向HashMap,插入顺序的LinkedHashMap,访问顺序的LinkedHashMap中插入四条数据,并在访问顺序的LinkedHashMap中按照4231 HashMap:1234 linkedHashMap ---with use:4231 可以看到,HashMap是无序的,遍历结果的顺序和插入顺序无关,是key值的自然排序,而LinkedHashMap LInkedHashMap怎么保存顺序的? 那么LinkedHashMap.Entry是什么呢?
LinkedHashMap简介 LinkedHashMap是HashMap的子类,与HashMap有着同样的存储结构,但它加入了一个双向链表的头结点,将所有put到LinkedHashmap的节点一一串成了一个双向循环链表 LinkedHashMap可以用来实现LRU算法(这会在下面的源码中进行分析)。 LinkedHashMap同样是非线程安全的,只在单线程环境下使用。 LinkedHashMap源码剖析 LinkedHashMap源码如下(加入了详细的注释): package java.util; import java.io.*; public 关于LinkedHashMap的源码,给出以下几点比较重要的总结: 1、从源码中可以看出,LinkedHashMap中加入了一个head头结点,将所有插入到该LinkedHashMap中的Entry按照插入的先后顺序依次加入到以 3、注意源码中的accessOrder标志位,当它false时,表示双向链表中的元素按照Entry插入LinkedHashMap到中的先后顺序排序,即每次put到LinkedHashMap中的Entry
其实可以认为HashMap的功能是LinkedHashMap的子集,HashMap可以做的LinkedHashMap都可以做。 其实可以认为HashMap的功能是LinkedHashMap的子集,HashMap可以做的LinkedHashMap都可以做。 = e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before LinkedHashMap中默认是false,也就是不移除。 import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K,V> extends LinkedHashMap
什么是 LinkedHashMap? 1.1 基本定位 LinkedHashMap 位于 java.util 包中,继承自 HashMap,实现了 Map 接口。 2.2 内部字段 transient LinkedHashMap.Entry<K,V> head; // 链表头(最旧) transient LinkedHashMap.Entry<K,V> tail; LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<>(hash, key, value, e); linkNodeLast = e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a 总结:LinkedHashMap 的设计哲学 LinkedHashMap 是 Java 集合框架中组合优于继承、扩展优于修改的经典范例: 复用:完全复用 HashMap 的高效哈希机制。
LinkedHashMap.Entry LinkedHashMap.Entry只是比HashMap.Node多了两个指针而已,LinkedHashMap.Entry直接就是双向链表的元素了。 在对LinkedHashMap进行put操作时,执行的是HashMap的put方法,多态调用LinkedHashMap的上述3个函数。 = e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a 和 HashMap 对比 LinkedHashMap 的应用场景? 现在有一个疑问,LinkedHashMap存在有什么意义?既然要维护一个双向链表,就不可能做到HashMap o(1)的时间复杂度。LinkedHashMap和直接使用双向链表有什么区别?
先看一下 LinkedHashMap 的类继承结构图: ? 可以看到 LinkedHashMap 继承了 HashMap。 我们知道 HashMap 是无序的,即迭代器的顺序与插入顺序没什么关系。 即遍历 LinkedHashMap 时,可以保持与插入顺序一致的顺序;或者与访问顺序一致的顺序。 LinkedHashMap 内部如何实现这两种顺序的呢?它是通过一个双链表来维持的。 因此可以将 LinkedHashMap 理解为「双链表 + 散列表」,或者“有序的散列表”。 如何能保持 LinkedHashMap 的顺序呢? LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); // 将新节点连接到列表末尾
0 前言 无序的 HashMap ,按 key 排序的 TreeMap ,那么 LinkedHashMap特点在哪呢 - 维护插入的顺序.LinkedHashMap 也同样出自于 Bloch之手(开发了整个 3.2 有参 构造一个空的LinkedHashMap实例,可自己指定初始容量,负载因子和排序模式. ? 构造一个维护插入顺序的LinkedHashMap实例,该实例具有与指定map相同的映射关系,创建的LinkedHashMap实例具有默认的加载因子(0.75)和足以容纳指定map中映射的初始容量. ? 蓝色部分是 HashMap 的方法 橙色部分为 LinkedHashMap 独有方法 注意 LinkedHashMap 虽然也是双向链表,但只提供单向的按插入的顺序从头到尾访问,不及 LinkedList 与插入操作一样,LinkedHashMap 删除操作相关的代码也是直接用父类的实现. 在删除节点时,父类不会修复 LinkedHashMap 的双向链表。