整理一下LinkedHashMap的用法

前情提要

在Leetcode上遇到这样一道题:

146. LRU缓存机制

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。
它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。

写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。

当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/lru-cache

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

当时第一想法是用HashMap存储(key,value),用LinkedList作为队列存储最近的使用情况。

但是看了参考答案之后,发现java中有种数据结构能够直接满足题目需求,那就是LinkedHashMap,官方给的代码乍一看也不太明白。

代码如下:

class LRUCache extends LinkedHashMap<Integer, Integer>{
    private int capacity;
    
    public LRUCache(int capacity) {
        super(capacity, 0.75F, true);
        this.capacity = capacity;
    }

    public int get(int key) {
        return super.getOrDefault(key, -1);
    }

    public void put(int key, int value) {
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity; 
    }
}

/**
 * LRUCache 对象会以如下语句构造和调用:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

LinkedHashMap

数据结构

LinkedHashMap继承于HashMap,结点类型如下:

    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }

对于它的结构,我们可以用一个图表示:

简单的说,LinkedHashMap其实就是在HashMap的基础上加入了双向链表,来保持顺序性,这个顺序默认是插入顺序,可以通过设置accessOrder设置为访问顺序。

具体可以参考这篇文章图解LinkedHashMap原理,写得很好很详细。

常用方法

(1)构造方法

LinkedHashMapt构造方法
方法 作用
LinkedHashMap() 用默认初始容量(16)和负载因子(0.75)构造空插入有序的LIKEDHHMAP实例
LinkedHashMap(int initialCapacity) 构造具有指定初始容量和默认负载因子(0.75)的空插入有序LinkedHashMap实例
LinkedHashMap(int initialCapacity, float loadFactor) 构造具有指定初始容量和负载因子的空插入有序LinkedHashMap实例
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) 构造具有指定初始容量、加载因子和排序模式的空LinkedHashMap实例
LinkedHashMap(Map<? extends K,? extends V> m) 构造具有与指定映射相同映射的插入顺序LinkedHashMap实例。
 

 

(2)常用方法

LinkedHashMap常用方法
返回值 方法 作用
void clear() 从此映射中删除所有映射。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回true。(如果存在value值,则返回true)
V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回null
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) 如果此映射应删除其最老项,则返回true(LRU,重写该方法设置条件)

(3)其他方法

其他方法诸如put、remove方法LinkedHashMap没有重写,所以可以通过调用父类HashMap的put、remove方法来实现。

参考文献

[1]https://www.jianshu.com/p/8f4f58b4b8ab.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章