java 基于LinkedHashMap的实现LRUCache

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 基于LinkedHashMap的实现LRUCache相关的知识,希望对你有一定的参考价值。

public class LRUCache<K, V> {
    private LinkedHashMap<K, V> map;
    private int cacheSize;
    private static final float DEFAULT_LOAD_FACTOR = 0.75f;

    public LRUCache(int cacheSize) {
        this.cacheSize = cacheSize;

        // 根据cacheSize和加载因子计算hashmap的capactiy,+1确保当达到cacheSize上限时不会触发hashmap的扩容
        int capacity = (int) Math.ceil(cacheSize / DEFAULT_LOAD_FACTOR) + 1;
        map = new LinkedHashMap<K, V>(capacity, DEFAULT_LOAD_FACTOR, true) {
            /**
             * 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>
             * <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>
             * <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>
             * <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.
             */
            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return size() > LRUCache.this.cacheSize;
            }
        };
    }

    public synchronized void put(K key, V value) {
        map.put(key, value);
    }

    public synchronized V get(K key) {
        return map.get(key);
    }

    public synchronized void remove(K key) {
        map.remove(key);
    }

    public synchronized int size() {
        return map.size();
    }

    public synchronized void clear() {
        map.clear();
    }

    public synchronized Set<Map.Entry<K, V>> getAll() {
        return map.entrySet();
    }

    /**
     * Returns a string representation of the object. In general, the
     * {@code toString} method returns a string that
     * "textually represents" this object. The result should
     * be a concise but informative representation that is easy for a
     * person to read.
     * It is recommended that all subclasses override this method.
     * <p>
     * The {@code toString} method for class {@code Object}
     * returns a string consisting of the name of the class of which the
     * object is an instance, the at-sign character `{@code @}', and
     * the unsigned hexadecimal representation of the hash code of the
     * object. In other words, this method returns a string equal to the
     * value of:
     * <blockquote>
     * <pre>
     * getClass().getName() + '@' + Integer.toHexString(hashCode())
     * </pre></blockquote>
     *
     * @return a string representation of the object.
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry entry : map.entrySet()) {
            sb.append(String.format("%s:%s ", entry.getKey(), entry.getValue()));
        }
        return sb.toString();
    }
}

以上是关于java 基于LinkedHashMap的实现LRUCache的主要内容,如果未能解决你的问题,请参考以下文章

JAVA集合LinkedHashMap及其源码分析

Java学习之LinkedHashMap

LinkedHashMap源码解读

Java源码分析LinkedHashMap源码分析

Java源码分析LinkedHashMap源码分析

java 集合框架-LinkedHashMap