LruMemoryCache 的一种实现

package com.lrumemorycache;

import android.graphics.Bitmap;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by guohongcheng on 2018/4/18.
 */

public class LruMemoryCache {
    private final static String TAG = "LruMemoryCache";

    private final LinkedHashMap<String, Bitmap> map; // 声明一个LinkedHashMap
    private final int maxSize; // 规定的最大存储空间
    private int size; // 已经存储的数量大小

    // 官方推荐maxSize一般声明为应用分配内存的1/8
    // 也可以用剩余内存的1/4
    // int maxMemory = (int) Runtime.getRuntime().maxMemory();
    public LruMemoryCache(int maxSize) {
        this.map = new LinkedHashMap<String, Bitmap>(0, 0.75f, true);
        this.maxSize = maxSize;
    }

    public final Bitmap get(String key) {
        if (key == null) {
            throw new NullPointerException("get() fail : key == null");
        }
        synchronized (this) {
            return map.get(key);
        }
    }

    public final boolean put(String key, Bitmap value) {
        if (key == null || value == null) {
            throw new NullPointerException("key == null");
        }

        synchronized (this) {
            size += sizeOf(key, value);
            Bitmap previous = map.put(key, value);
            if (previous != null) {
                size -= sizeOf(key, value);
            }
        }
        trim2Size(maxSize);

        return true;
    }

    /*
    * 返回 value 的字节数
    * 当entry保存到cache中后,它占用的内存大小保持稳定
    * */
    private int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight();
    }

    /*
    * 每次插入都会做检查,当插入entry后,超出了map的maxSize,
    * 就需要不断删除最老的entry,直到map的大小 小于maxSize
    * Remove the eldest entries until the total of remaining entries is at or
    * below the requested size.
    * @param maxSize the maximum size of the cache before returning. May be -1 to evict even 0-sized elements.
    *
    * */
    private void trim2Size(int maxSize) {
        while (true) {
            String key;
            Bitmap value;
            synchronized (this) {
                // 如果当前map大小小于0 或者
                // 当前map是空,但map大小不为零
                // 那么就抛出状态异常
                if (size < 0 || (map.isEmpty() && size != 0)) {
                    throw new IllegalStateException(getClass().getName()
                            + ".sizeOf() is reporting  inConsistent results!");
                }

                // map没有超过限制, 或  当前map是空的。   退出while循环
                if (size <= maxSize || map.isEmpty()) {
                    break;
                }

                Map.Entry<String, Bitmap> toEvict = map.entrySet().iterator().next();
                if (toEvict == null) {
                    break;
                }

                key = toEvict.getKey();
                value = toEvict.getValue();
                map.remove(key);
                size -= sizeOf(key, value);
            }
        }
    }

    /**
     * 移除已存在的元素实体
     * Removes the entry for {@code key} if it exists.
     *
     * @return the previous value mapped by {@code key}.
     */
    public final Bitmap remove(String key) {
        if (key == null) {
            throw new NullPointerException("key == null");
        }

        synchronized (this) {
            Bitmap previous = map.remove(key);
            if (previous != null) {
                size -= sizeOf(key, previous);
            }
            return previous;
        }
    }

    /*
    * 在适当的时机调用,清空map
    * */
    public void clear() {
        trim2Size(-1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值