走进JDK(十一)------LinkedHashMap】的更多相关文章

概述LinkedHashMap 继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 HashMap 不能随时保持遍历顺序和插入顺序一致的问题.除此之外,LinkedHashMap 对访问顺序也提供了相关支持. 原理LinkedHashMap在HashMap结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序. 上图中,淡蓝色的箭头表示前驱引用,红色箭头表示后继引用.每当有新键值对节点插入,新节点最终会接在 tail 引用指向的节点后面.而 tai…
debug 模式 ,在fis=new FileInputStream(file); 行打断点 调试过程中发现按f5无法走进jdk源码 package com.lzl.spring.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import…
有人说HashMap是jdk中最难的类,重要性不用多说了,敲过代码的应该都懂,那么一起啃下这个硬骨头吧!一.哈希表在了解HashMap之前,先看看啥是哈希表,首先回顾下数组以及链表数组:采用一段连续的存储单元来存储数据.对于指定下标的查找,时间复杂度为O(1):通过给定值进行查找,需要遍历数组,逐一比对给定关键字和数组元素,时间复杂度为O(n),当然,对于有序数组,则可采用二分查找,插值查找,斐波那契查找等方式,可将查找复杂度提高为O(logn):对于一般的插入删除操作,涉及到数组元素的移动,其…
说完了list,再说说colletion另外一个重要的子集set,set里不允许有重复数据,但是不是无序的.先看下set的整个架构吧: 一.类定义 public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> 这地方跟之前的地方一样,为啥继承了AbstractCollection<E>还需要实现Set<E>呢?前面ArrayList的文章已…
阅读JDK源码也是一件非常重要的事情,尤其是使用频率最高的一些类,通过源码可以清晰的清楚其内部机制. 如何阅读jdk源码(基于java8)? 首先找到本地电脑中的jdk安装路径,例如我的就是E:\jdk, src.zip中就包含了jdk的所有源码,并将相关源码导入到ideal.eclipse等等,如图: 第一步就来介绍所有类的基类Object,先看下此类的架构图:  一.registerNatives private static native void registerNatives(); s…
一.类定义 TreeMap的类结构: public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable TreeMap 是一个有序的key-value集合,它是通过红黑树实现的. TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合. TreeMap 实现了Navigab…
本文基于java8. 基本概念: Jvm 内存中 String 的表示是采用 unicode 编码 UTF-8 是 Unicode 的实现方式之一 一.String定义 public final class String implements java.io.Serializable, Comparable<String>, CharSequence String是个final类,不允许继承.并且实现了Serializable, Comparable<String>, CharSe…
map其实就是键值对,要想学习好map,得先从AbstractMap开始. 一.类定义.构造函数.成员变量 public abstract class AbstractMap<K,V> implements Map<K,V> protected AbstractMap() { } 这是个抽象类,很明显只是为子类们提供一些共用的方法模板. 成员变量: transient Set<K> keySet;//说明abstractMap中的key是不允许重复的 transient…
要学习LinkedList,首先得了解链表结构.上篇介绍ArrayList的文章中介绍了底层是数组结构,查询快的问题,但是删除时,需要将删除位置后面的元素全部左移,因此效率比较低. 链表则是这种机制: 此图展示的是一个单向列表,单向链表只能向一个方向遍历.链表中存在一系列的节点(node),每个node中维护了一个data以及一个next链,data则保存当前node所需要保存的数据,而next链指向下一个元素,最后一个node的next指向null. 这个则是个典型的双向链表,双向链表中一共存…
对于广大java程序员来说,ArrayList的使用是非常广泛的,但是发现很多工作了好几年的程序员不知道底层是啥...这我觉得对于以后的发展是非常不利的,因为java中的每种数据结构的设计都是非常完善的,学习了这种思想,在设计自己的容器是非常有帮助的. 一.ArrayList底层结构 ArrayList的底层其实就是一个数组,数组的劣势想必也不用多说,一旦创建,长度无法更改.而ArrayList则可以不停的add或是remove,也可以称之为动态数组. 二.类定义以及成员变量 1.类定义 //1…
接下来的一段时间重点介绍java.util这个包中的内容,这个包厉害了,包含了collection与map,提供了集合.队列.映射等实现.一张图了解java中的集合类: AbstractList 一.list简介 list是啥?为啥会有list的存在呢?java中的数组相信大家都是非常熟悉的,可以存放多个数据,但是数组有一个缺点,就是数组在创建之后,长度就不可更改(但是针对于数组的元素可以更改),若你需要在后续过程中往数组中添加数据,那麻烦了,不支持. list在java中是collection…
InputStream InputStream是java中的输入流,下面基于java8来分析下InputStream源码 一.类定义 public abstract class InputStream implements Closeable Closeable接口定义了close()方法,流在使用完之后需要关闭,并且放在finally块中操作比较好. 二.变量 // 该变量用于确定在skip方法中使用的最大缓存数组大小. private static final int MAX_SKIP_BU…
AbstractStringBuilder是一个抽象类,StringBuffer.StringBuilder则继承AbstractStringBuilder,所以先说AbstractStringBuilder. AbstractStringBuilder 一.AbstractStringBuilder //实现了两个接口,其中CharSequence这个字符序列的接口已经很熟悉了: //1.该接口规定了需要实现该字符序列的长度:length(): //可以取得下标为index的的字符:charA…
目录 LinkedHashMap概述 内部字段及构造方法 存储元素 取出元素 删除元素 迭代器 利用LinkedHashMap简单实现LRU算法 总结 LinkedHashMap概述   JDK对LinkedHashMap的介绍: Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from Has…
个人觉得LinkedHashMap 存在的意义就是为了实现 LRU 算法. public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.…
update1:第二个实现,读操作不必要采用独占锁,缓存显然是读多于写,读的时候一开始用独占锁是考虑到要递增计数和更新时间戳要加锁,不过这两个变量都是采用原子变量,因此也不必采用独占锁,修改为读写锁.update2:一个错误,老是写错关键字啊,LRUCache的maxCapacity应该声明为volatile,而不是transient.      最简单的LRU算法实现,就是利用jdk的LinkedHashMap,覆写其中的removeEldestEntry(Map.Entry)方法即可,如下所…
1. 前言 2018年9月,伴随着java 11的发布,内置的httpclient正式登上了历史的舞台.此前,JDK内置的http工具URLConnection性能羸弱,操作繁琐,饱受诟病,也因此令如Apache 的 Httpclient, Square的 OKHttp 这样的第三方客户端大放异彩.新生的JDK Httpclient,拥抱了响应式流(Reactive Stream)模型,使用了JAVA 9引入的Flow api,并运用completableFuture使调用流程异步化(在IO层面…
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高". 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的…
最简单的LRU算法实现,就是利用jdk的LinkedHashMap,覆写其中的removeEldestEntry(Map.Entry)方法即可,如下所示: java 代码 import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.R…
JDK中的实现 在JDK中LinkedHashMap可以作为LRU算法以及插入顺序的实现,LinkedHashMap继承自HashMap,底层结合hash表和双向链表,元素的插入和查询等操作通过计算hash值找到其数组位置,在做插入或则查询操作是,将元素插入到链表的表头(当然得先删除链表中的老元素),如果容量满了,则删除LRU这个元素,在链表表尾的元素即是. LinkedHashMap的时间复杂度和HashMap差不多,双向链表的删除和表头插入等操作都是O(1)复杂度,故不会影响HashMap的…
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的.周期性的…
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的.周期性的…
概述 Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码.而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译.Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行.Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行.这就是Java的能…
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的.周期性的…
(转自:http://flychao88.iteye.com/blog/1977653) 1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢…
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的.周期性的…
前言 上篇文章 深入理解 Handler 消息机制 中提到了获取线程的 Looper 是通过 ThreadLocal 来实现的: public static @Nullable Looper myLooper() { return sThreadLocal.get(); } 每个线程都有自己的 Looper,它们之间不应该有任何交集,互不干扰,我们把这种变量称为 线程局部变量 .而 ThreadLocal 的作用正是存储线程局部变量,每个线程中存储的都是独立存在的数据副本.如果你还是不太理解,看…
一.引子 本文搜集从各种资源上搜集高频面试算法,慢慢填充...每个算法都亲测可运行,原理有注释.Talk is cheap,show me the code! 走你~ 二.常见算法 2.1 判断单向链表是否有环 package study.algorithm.interview; /** * 判断单向链表是否有环? <p>Q1:判断是否有环? isCycle </> <p>Q2:环长? count </> <p>Q3: 相遇点? p1.data…
ThreadLocal 是一个老生常谈的问题,在源码学习以及实际项目研发中,往往都能见到它的踪影,用途比较广泛,所以有必要深入一番. 敢问,ThreadLocal 都用到了哪里?有没有运用它去解决过业务问题呢? 没用过.答不上来也没关系,因为通过今天的分享,能让你轻松 get 如下几点,收获满满. a)ThreadLocal 快速入门: b)ThreadLocal 源码解读: c)ThreadLocal 使用场景: d)ThreadLocal 阿里规约中的奇技淫巧. 1. ThreadLocal…
目录 概念 方法选择 实现方案(基于LinkedHashMap) 改进方案 1.LRU-K 2.Two queue 3.Multi Queue(MQ) LRU类算法对比 LRU 在 Redis 中的应用 概念 RU是Least Recently Used 的缩写,翻译过来就是"最近最少使用". LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小.也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰. 方法选择 用一个数组来存…