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() &gt; 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相关推荐

  1. Java集合类学习总结

    Java集合类学习总结 这篇总结是基于之前博客内容的一个整理和回顾. 这里先简单地总结一下,更多详细内容请参考我的专栏:深入浅出Java核心技术 https://blog.csdn.net/colum ...

  2. JAVA视频学习笔记-马士兵(七)

    `JAVA视频学习笔记-马士兵` 容器_API_Collection1(20200622) 容器_Collection2(20200623) 容器_Iterator(20200624) 容器_Enha ...

  3. 黑马程序员Java教程学习笔记(五)

    学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(五) 日期时间:Date.Sim ...

  4. Java NIO 学习笔记(三)----Selector

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  5. 可能是最全面的 Java G1学习笔记

    转载自 可能是最全面的 Java G1学习笔记 引子 最近遇到很多朋友过来咨询G1调优的问题,我自己去年有专门学过一次G1,但是当时只是看了个皮毛,因此自己也有不少问题.总体来讲,对于G1我有几个疑惑 ...

  6. 深入浅出 Java CMS 学习笔记

    转载自  深入浅出 Java CMS 学习笔记 引子 带着问题去学习一个东西,才会有目标感,我先把一直以来自己对CMS的一些疑惑罗列了下,希望这篇学习笔记能解决掉这些疑惑,希望也能对你有所帮助. 1. ...

  7. Java NIO学习笔记之图解ByteBuffer

    转载自 Java NIO学习笔记之图解ByteBuffer ByteBuffer前前后后看过好几次了,实际使用也用了一些,总觉得条理不够清晰. <程序员的思维修炼>一本书讲过,主动学习,要 ...

  8. 转载:mongoDB java驱动学习笔记

    http://www.blogjava.net/watchzerg/archive/2012/09/22/388346.html mongoDB java驱动学习笔记 指定新mongo实例: Mong ...

  9. 2019年Java Web学习笔记目录

    Java Web学习笔记目录 1.Java Web学习笔记01:动态网站初体验 2.Java Web学习笔记02:在Intellij里创建Web项目 3.Java Web学习笔记03:JSP元素 4. ...

最新文章

  1. 0 - python简介
  2. Smali源代码分析教程(转)
  3. SpringCloud基本模块分配搭建以及负载均衡
  4. C++17尝鲜:类模板中的模板参数自动推导
  5. 批处理 设置电脑最佳性能_批处理最佳做法
  6. SQL 语句时间比较
  7. 【实践驱动开发3-003】TI WL1835MODCOM8 在android的移植 - 软件获取2
  8. mysql数据库事务隔离级别
  9. STM32-串行SPI nor
  10. chatbot使用_使用Python设计ChatBot:一种改进的方法
  11. WPF Bitmap转成Imagesource的性能优化
  12. 经验分享:如何做好产品可行性分析?
  13. Soul打造冬奥捏脸大赛 在创意玩法中传递奥运精神
  14. 2016年腾讯校招笔试题 详解
  15. mysql安装时初始密码错误_踩坑之MySQL安装及修改初始密码
  16. 不同范数下的余弦定理_平行四边形的认识视频
  17. 华为防火墙的基本安全策略
  18. oracle数据库在mybatis中的数值类型(NUMBER型)
  19. 关于使用网页做托福TPO在chrome上没有声音,找不到autoplay-policy
  20. Buffer Busy Waits的两个结论

热门文章

  1. python恶搞表情包-哈哈!我用 Python 把你的朋友变成表情包了
  2. python可以做什么系统-用python做推荐系统(一)
  3. python如何爬虫网页数据-python爬虫——爬取网页数据和解析数据
  4. python与c语言在语法上的区别-C语言和Python编程先学习哪个
  5. python怎么学最快-浅谈:从为什么学习python到如何学好python
  6. python教程第四版pdf下载-笨办法学python 第四版 中文pdf高清版
  7. python装饰器函数-【python3】 函数 装饰器
  8. python快速编程答案-100+Python编程题带你快速上手(附答案)
  9. python学习手册条件-Python学习手册(第4版)pdf
  10. 自学python需要多长时间-零基础自学python要多久?