美文网首页
56 手写LRU缓存淘汰算法与HashMap如何降低Hash冲突

56 手写LRU缓存淘汰算法与HashMap如何降低Hash冲突

作者: 滔滔逐浪 | 来源:发表于2020-09-21 19:12 被阅读0次

    HashMap底层是有序存放的吗?
    无序、散列存放
    遍历的时候从数组0开始遍历每个链表,遍历结果存储顺序不保证一致。
    如果需要根据存储顺序保存,可以使用LinkedHashMap底层是基于双向链表存放
    LinkedHashMap基于双向链表实现
    HashMap基本单向链表实现

    LinkedHashMap实现缓存淘汰框架

    LRU(最近少使用)缓存淘汰算法
    LFU(最不经常使用算法)缓存淘汰算法
    ARC(自适应缓存替换算法)缓存淘汰算法
    FIFO(先进先出算法)缓存淘汰算法
    MRU(最近最常使用算法)缓存淘汰算法

    LinkedHashMap基于双向链表实现,可以分为插入或者访问顺序两种,采用双链表的形式保证有序
    可以根据插入或者读取顺序

    LinkedHashMap是HashMap的子类,但是内部还有一个双向链表维护键值对的顺序,每个键值对既位于哈希表中,也位于双向链表中。LinkedHashMap支持两种顺序插入顺序 、 访问顺序

    插入顺序:先添加的在前面,后添加的在后面。修改操作不影响顺序
    执行get/put操作后,其对应的键值对会移动到链表末尾,所以最末尾的是最近访问的,最开始的是最久没有被访问的,这就是访问顺序。
    其中参数accessOrder就是用来指定是否按访问顺序,如果为true,就是访问顺序,false根据新增顺序

    package com.taotao.hashmap001;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     *@author tom
     *Date  2020/9/21 0021 19:48
     *缓存淘汰策略  访问顺序  get/put操作后其对应的键值会移动到末尾
     */
    public class LruCache<K,V>extends LinkedHashMap<K,V> {
        /**
         * 容量
         */
        private int  capacity;
    
        public LruCache(int capacity){
            super(capacity,0.75f,true);
            this.capacity=capacity;
        }
        @Override
        protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
           return  size()>capacity;
        }
    
        public static void main(String[] args) {
            LruCache<String,String> lruCache=new LruCache<>(3);
     lruCache.put("a","a");
     lruCache.put("b","b");
     lruCache.put("c","c");
     lruCache.put("d","d");
     lruCache.forEach((k,v)->{
         System.out.println("k= "+k);
     });
    
        }
    }
    
    
    

    hashMap 如何降低hash冲突概率:

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    ((p = tab[i = (n - 1) & hash])
    
    

    1、保证不会发生数组越界
    首先我们要知道的是,在HashMap,数组的长度按规定一定是2的幂。因此,数组的长度的二进制形式是:10000…000, 1后面有偶数个0。 那么,length - 1 的二进制形式就是01111.111, 0后面有偶数个1。最高位是0, 和hash值相“与”,结果值一定不会比数组的长度值大,因此也就不会发生数组越界。一个哈希值是8,二进制是1000,一个哈希值是9,二进制是1001。和1111“与”运算后,结果分别是1000和1001,它们被分配在了数组的不同位置,这样,哈希的分布非常均匀。

    相关文章

      网友评论

          本文标题:56 手写LRU缓存淘汰算法与HashMap如何降低Hash冲突

          本文链接:https://www.haomeiwen.com/subject/sbhbyktx.html