6 手写Java LinkedHashMap 核心源码
概述
LinkedHashMap是Java中常用的数据结构之一,安卓中的LruCache缓存,底层使用的就是LinkedHashMap,LRU(Least Recently Used)算法,即最近最少使用算法,核心思想就是当缓存满时,会优先淘汰那些近期最少使用的缓存对象
LruCache的缓存算法
LruCache采用的缓存算法为LRU(Least Recently Used),最近最少使用算法。核心思想是当缓存满时,会首先把那些近期最少使用的缓存对象淘汰掉
LruCache的实现
LruCache底层就是用LinkedHashMap来实现的。提供 get 和 put 方法来完成对象的添加和获取
LinkedHashMap与HashMap的区别
相同点: 1. 都是key,value进行添加和获取 2. 底层都是使用数组来存放数据 不同点: 1. HashMap是无序的,LinkedHashMap是有序的(插入顺序和访问顺序) 2. LinkedHashMap内存的节点存放在数据中,但是节点内部有两个指针,来完成双向链表的操作,来保证节点插入顺序或者访问顺序
LinkedHashMap的使用
LinkedHashMap插入顺序的演示代码
public static void main(String[] args) { //默认记录的就是插入顺序 Map<String, String> map = new LinkedHashMap<>(); map.put("name", "tom"); map.put("age", "34"); map.put("address", "beijing"); Iterator iterator = map.entrySet().iterator(); //遍历 while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println("Key = " + key + ", Value = " + value); } }
输出如下:
Key = name, Value = tom Key = age, Value = 34 Key = address, Value = beijing
由输出可以看到
我们往LinedHashMap中分别按顺序插入了name,age,address以及对应的value
遍历的时候,也是按顺序分别输出了 name,age,address以及对应的value
所以可以,LinkedHashMap默认记录的就是插入的顺序
作为比较,我们再看来一下 HashMap 的遍历是不是有序的。就以上面这几个值为例
代码以及输出如下:
HashMap的遍历
public static void main(String[] args) { //插入和上面一样的值 Map<String, String> map = new HashMap<>(); map.put("name", "tom"); map.put("age", "34"); map.put("address", "beijing"); Iterator iterator = map.entrySet().iterator(); //遍历 while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println("Key = " + key + ", Value = " + value); } }
输出如下
Key = address, Value = beijing Key = name, Value = tom Key = age, Value = 34
从上面可以得知:
- HashMap遍历的时候,是无序的,和插入的顺序是不相关的。
- LinkedHashMap默认的顺序是记录插入顺序
既然LinkedHashMap默认是按着插入顺序的,那么肯定也有其它的顺序。
对的,LinkedHashMap还可以记录访问的顺序。访问过的元素放在链表前面
遍历的时候最近访问的元素最后才遍历到
LinkedHashMap的访问顺序的演示代码
public static void main(String[] args) { /** * 第一个参数:数组的大小 * 第二个参数:扩容因子,和HashMap一样,添加的元素的个数达到 16 * 0.75时,开始扩容 * 第三个参数:true:表示记录访问顺序 * false:表示记录插入顺序(默认的顺序) */ Map<String, String> map = new LinkedHashMap<>(16,0.75f,true); //分别插入下面几个值 map.put(