java集合类学习笔记之LinkedHashMap
1、简述
LinkedHashMap是HashMap的子类,他们最大的不同是,HashMap内部维护的是一个单向的链表数组,而LinkedHashMap内部维护的是一个双向的链表数组。HashMap是无序的,LinkedHashMap可以根据访问顺序或者插入顺序进行排序(默认是根据插入顺序的,当设置accessOrder为true时会按照访问顺序排序),当按照访问顺序排序的时候,每次get或put操作时,都会将该节点放到链表的末尾
2、实现
1、数据结构:
LinkedHashMap是HashMap的子类,它的内部同样是使用了hashMap定义的链表数组存储的数据。只不过在HashMap中使用的是单想链表Node<k,v>作为每个节点,而LinkedHashMap使用了集成了HashMap.Node<k,v>的双向链表Entry<k,v>来作为每个节点,Entry<k,v>在Node<k,v>的基础上增加了Entry<K,V> before, after两个属性,将数组中的前后元素关联起来,这样的实现也为LinkedHashMap根据插入顺序或访问顺序提供了可能
2、构造方法:
LinkedHashMap是HashMap的子类,它提供了五种构造方法,
public LinkedHashMap(int initialCapacity, float loadFactor) {super(initialCapacity, loadFactor);accessOrder = false;} public LinkedHashMap(int initialCapacity) {super(initialCapacity);accessOrder = false;} public LinkedHashMap() {super();accessOrder = false;} public LinkedHashMap(Map<? extends K, ? extends V> m) {super();accessOrder = false;putMapEntries(m, false);} public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder) {super(initialCapacity, loadFactor);this.accessOrder = accessOrder;}
从以上我们可以看出,前面四中构造方法都是默认的accessOrder=false,即按找插入顺序排序,第五种构造方法我们可以自己定义accessOrder的值,当为true时,说明是按照访问顺序排序的,每次put或get操作的时候都会将元素移到链表的末尾
3、LinkedHashMap操作
由于LinkedHashMap继承了HashMap类,而且并没有重写put,get等方法,所以在这里对于LinkedHashMap的基础操作的源码就不再分析,感兴趣的可以参考上一篇关于HashMap的学习笔记。在这里重点看一下LinkedHashMap提供的removeEldestEntry(Map.Entry<K,V> eldest)方法
/*** Returns <tt>true</tt> if this map should remove its eldest entry.* This method is invoked by <tt>put</tt> and <tt>putAll</tt> after* inserting a new entry into the map. It provides the implementor* with the opportunity to remove the eldest entry each time a new one* is added. This is useful if the map represents a cache: it allows* the map to reduce memory consumption by deleting stale entries.** <p>Sample use: this override will allow the map to grow up to 100* entries and then delete the eldest entry each time a new entry is* added, maintaining a steady state of 100 entries.* <pre>* private static final int MAX_ENTRIES = 100;** protected boolean removeEldestEntry(Map.Entry eldest) {* return size() > MAX_ENTRIES;* }* </pre>** <p>This method typically does not modify the map in any way,* instead allowing the map to modify itself as directed by its* return value. It <i>is</i> permitted for this method to modify* the map directly, but if it does so, it <i>must</i> return* <tt>false</tt> (indicating that the map should not attempt any* further modification). The effects of returning <tt>true</tt>* after modifying the map from within this method are unspecified.** <p>This implementation merely returns <tt>false</tt> (so that this* map acts like a normal map - the eldest element is never removed).** @param eldest The least recently inserted entry in the map, or if* this is an access-ordered map, the least recently accessed* entry. This is the entry that will be removed it this* method returns <tt>true</tt>. If the map was empty prior* to the <tt>put</tt> or <tt>putAll</tt> invocation resulting* in this invocation, this will be the entry that was just* inserted; in other words, if the map contains a single* entry, the eldest entry is also the newest.* @return <tt>true</tt> if the eldest entry should be removed* from the map; <tt>false</tt> if it should be retained.*/protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {return false;}
这个方法就是判断是否需要删除LinkedHashMap中最旧的元素,默认是false的。当我们需要利用hashmap做一些数据的缓存,可能有的数据是使用了一两次之后就失去了价值,此外我们也不想看到缓存的map无限的增长又不想自己手动的去维护这个map。此时我们就可以使用LinkedHashMap来完成这个功能;
public class Demo {static class MyMap<k,v> extends LinkedHashMap<k,v>{ //定义一个继承LinkedHashMap的类,并重写removeEldestEntry方法int size;public MyMap (int size){ //只提供一个有参的构造方法,用来设置map的大小/** 这里调用的是LinkedHashMap的LinkedHashMap(int initialCapacity,boolean accessOrder)* 构造方法,设置按访问顺序排序*/super(16,0.75f,true); this.size = size;}@Overrideprotected boolean removeEldestEntry(Entry<k, v> eldest) {// TODO Auto-generated method stubreturn this.size<size(); //设置当map里面存放的元素超过MyMap设置的size时就删除最老的元素 }}public static void main(String[] args) {Map<String,String> map = new MyMap<String,String>(5); for (int i = 0; i < 10; i++) {map.put(i+"", i+"");System.out.print(i+"="+map.size()+"\t");}System.out.println();//遍历map看看里面的元素map.forEach((k,v)->{System.out.println("k="+k);});//此时访问一下里面的元素,再观察遍历后的顺序map.get("6");map.get("8");System.out.println("========================");map.forEach((k,v)->{System.out.println("k="+k);});} } 打印的结果:
0=1 1=2 2=3 3=4 4=5 5=5 6=5 7=5 8=5 9=5
k=5
k=6
k=7
k=8
k=9
========================
k=5
k=7
k=9
k=6
k=8
总结:
在学完LinkedHashMap和HashMap之后我们会发现,这两种集合类是非常相似的,二者都是通过内部数组去保存数据的,不同的是HashMap数组中的每个元素都是一个单向的链表,指向了产生hash冲突时和它本身具有相同hash值的元素,所以HashMap只能是无序的。LinkedHashMap中数组里面的每一个元素都是一个双向链表,它不仅指向了产生hash冲突时下一个跟它本身具有相同hash值的位置,还指定了它的上一个和下一个元素(可以是插入顺序的上一个下一个,也可以试访问顺序的上一个下一个),这样为LinkedHashMap实现有序提供了可能
转载于:https://www.cnblogs.com/gulang-jx/p/8082340.html
java集合类学习笔记之LinkedHashMap相关推荐
- Java集合类学习总结
Java集合类学习总结 这篇总结是基于之前博客内容的一个整理和回顾. 这里先简单地总结一下,更多详细内容请参考我的专栏:深入浅出Java核心技术 https://blog.csdn.net/colum ...
- JAVA视频学习笔记-马士兵(七)
`JAVA视频学习笔记-马士兵` 容器_API_Collection1(20200622) 容器_Collection2(20200623) 容器_Iterator(20200624) 容器_Enha ...
- 黑马程序员Java教程学习笔记(五)
学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(五) 日期时间:Date.Sim ...
- Java NIO 学习笔记(三)----Selector
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- 可能是最全面的 Java G1学习笔记
转载自 可能是最全面的 Java G1学习笔记 引子 最近遇到很多朋友过来咨询G1调优的问题,我自己去年有专门学过一次G1,但是当时只是看了个皮毛,因此自己也有不少问题.总体来讲,对于G1我有几个疑惑 ...
- 深入浅出 Java CMS 学习笔记
转载自 深入浅出 Java CMS 学习笔记 引子 带着问题去学习一个东西,才会有目标感,我先把一直以来自己对CMS的一些疑惑罗列了下,希望这篇学习笔记能解决掉这些疑惑,希望也能对你有所帮助. 1. ...
- Java NIO学习笔记之图解ByteBuffer
转载自 Java NIO学习笔记之图解ByteBuffer ByteBuffer前前后后看过好几次了,实际使用也用了一些,总觉得条理不够清晰. <程序员的思维修炼>一本书讲过,主动学习,要 ...
- 转载:mongoDB java驱动学习笔记
http://www.blogjava.net/watchzerg/archive/2012/09/22/388346.html mongoDB java驱动学习笔记 指定新mongo实例: Mong ...
- 2019年Java Web学习笔记目录
Java Web学习笔记目录 1.Java Web学习笔记01:动态网站初体验 2.Java Web学习笔记02:在Intellij里创建Web项目 3.Java Web学习笔记03:JSP元素 4. ...
最新文章
- 0 - python简介
- Smali源代码分析教程(转)
- SpringCloud基本模块分配搭建以及负载均衡
- C++17尝鲜:类模板中的模板参数自动推导
- 批处理 设置电脑最佳性能_批处理最佳做法
- SQL 语句时间比较
- 【实践驱动开发3-003】TI WL1835MODCOM8 在android的移植 - 软件获取2
- mysql数据库事务隔离级别
- STM32-串行SPI nor
- chatbot使用_使用Python设计ChatBot:一种改进的方法
- WPF Bitmap转成Imagesource的性能优化
- 经验分享:如何做好产品可行性分析?
- Soul打造冬奥捏脸大赛 在创意玩法中传递奥运精神
- 2016年腾讯校招笔试题 详解
- mysql安装时初始密码错误_踩坑之MySQL安装及修改初始密码
- 不同范数下的余弦定理_平行四边形的认识视频
- 华为防火墙的基本安全策略
- oracle数据库在mybatis中的数值类型(NUMBER型)
- 关于使用网页做托福TPO在chrome上没有声音,找不到autoplay-policy
- Buffer Busy Waits的两个结论
热门文章
- python恶搞表情包-哈哈!我用 Python 把你的朋友变成表情包了
- python可以做什么系统-用python做推荐系统(一)
- python如何爬虫网页数据-python爬虫——爬取网页数据和解析数据
- python与c语言在语法上的区别-C语言和Python编程先学习哪个
- python怎么学最快-浅谈:从为什么学习python到如何学好python
- python教程第四版pdf下载-笨办法学python 第四版 中文pdf高清版
- python装饰器函数-【python3】 函数 装饰器
- python快速编程答案-100+Python编程题带你快速上手(附答案)
- python学习手册条件-Python学习手册(第4版)pdf
- 自学python需要多长时间-零基础自学python要多久?