LRU算法的实现

2021-03-15 07:33

阅读:463

标签:链表   等于   row   ==   双向链表   package   头结点   hash   else   

缘由:看到redis的缓存淘汰机制,便自己实现了一下

代码实现(双向链表+HashMap)

package com.jarjune.jdalao.framework.algorithm;

import java.util.*;

/**
 * LRU
 * @author jarjune
 * @version 1.0.1
 * @date 2020/11/19
 */
public class LRUCache {

    // 缓存Node
    private Map> cache;

    // 双向链表首结点
    private Node first;

    // 双向链表尾结点
    private Node last;

    // 最大缓存容量
    private int capacity;

    public LRUCache(int capacity) throws Exception {
        if(capacity ((int) (capacity / 0.75f + 1));
        this.capacity = capacity;
    }

    private class Node {
        K k;
        V v;
        Node prev;
        Node next;

        Node(K k, V v) {
            this.k = k;
            this.v = v;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "k=" + k +
                    ", v=" + v +
                    ‘}‘;
        }
    }

    public int size() {
        return cache.size();
    }

    public void put(K k, V v) {

        Node node = cache.get(k);
        if(null == node) {
            node = new Node(k, v);

            // 大于等于capacity容量最大值时
            if(cache.size() >= capacity) {

                if(null != last) {
                    // 移除最后一个元素的缓存
                    cache.remove(last.k);

                    last = last.prev;
                    if(null == last) {
                        first = null;
                    } else {
                        last.next = null;
                    }
                }
            }
            cache.put(k, node);
        } else {
            node.v = v;
        }

        moveToFirst(node);
    }

    /**
     *  1(first)
     * ↑  ↓
     *  2(node)
     * ↑  ↓
     *  3
     * ↑  ↓
     *  4(last)
     */
    private void moveToFirst(Node node) {

        if(first == null || last == null) {
            first = last = node;
            return;
        }

        // 如果是头结点就结束
        if(node == first) {
            return;
        }

        // 如果是尾结点,尾结点就等于当前结点的上一个结点
        if(node == last) {
            last = node.prev;
        }

        if(null != node.next) {
            node.next.prev = node.prev;
        }

        if(null != node.prev) {
            node.prev.next = node.next;
        }

        node.next = first;
        first.prev = node;
        node.prev = null;
        first = node;
    }

    class LRUIterable implements Iterable> {

        @Override
        public Iterator> iterator() {
            return new Iterator>() {

                private Node node = first;

                @Override
                public boolean hasNext() {
                    return node != null;
                }

                @Override
                public Node next() {
                    Node tmp = node;
                    node = node.next;
                    return tmp;
                }
            };
        }
    }

    public Iterator> iterator() {
        return new LRUIterable().iterator();
    }

    public Set keySet() {
        Iterator> iterator = iterator();
        Set keys = new LinkedHashSet();
        while(iterator.hasNext()) {
            keys.add(iterator.next().k);
        }
        return keys;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (Node node: new LRUIterable()) {
            sb.append(node);
        }
        return sb.toString();
    }
}

搞定

LRU算法的实现

标签:链表   等于   row   ==   双向链表   package   头结点   hash   else   

原文地址:https://www.cnblogs.com/jarjune/p/14010351.html


评论


亲,登录后才可以留言!