java超时Map,模拟redis

package com.qxs.business.reform.utils;

import java.util.*;

/**
 * 超时Map,模拟redis超时
 */
public class ExpiryMap<K, V> extends HashMap<K, V> {
    private long EXPIRY = 1000*60*60*6;// 默认缓存超时时间 6小时
 
    private static ExpiryMap<String, Object> dataMap;
 
    private HashMap<K, Long> timeMap = new HashMap<>();// 存储过期时间

    private int num = 0;// 一个计数器
 
    private ExpiryMap() {}// 构造器私有化
 
    // 采用单例模式获取实例
    public static ExpiryMap getInstance() {
        if (null == dataMap) {
            dataMap = new ExpiryMap<>();
        }
        return dataMap;
    }
 
    @Override
    public V put(K key, V value) {
        timeMap.put(key, System.currentTimeMillis() + EXPIRY);
        return super.put(key, value);
    }
 
    public V put(K key, V value, long expiryTime) {
        timeMap.put(key, System.currentTimeMillis() + expiryTime);
        return super.put(key, value);
    }
 
    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            timeMap.put(e.getKey(), System.currentTimeMillis() + EXPIRY);
        }
        super.putAll(m);
    }
 
    public void putAll(Map<? extends K, ? extends V> m, long expiryTime) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            timeMap.put(e.getKey(), System.currentTimeMillis() + expiryTime);
        }
        super.putAll(m);
    }
 
    @Override
    public V get(Object key) {
        if (key == null) {
            return null;
        }
        if(checkExpiry(key, true)) {
            return null;
        }
        return super.get(key);
    }
 
    @Override
    public V remove(Object key) {
        timeMap.remove(key);
        return super.remove(key);
    }
 
    @Override
    public void clear() {
        timeMap.clear();
        super.clear();
    }
 
    @Override
    public boolean containsKey(Object key) {
        num++;
        if (num > 100) {
            num = 0;
            delAllExpiry();// 每调用该方法100次,检测一下所有已经过期的key,进行删除
        }
        return !checkExpiry(key, true) && super.containsKey(key);
    }
 
    @Override
    public boolean containsValue(Object value) {
        if (value == null) {
            return Boolean.FALSE;
        }
        Boolean flag = Boolean.FALSE;
        Set<Entry<K, V>> entries = super.entrySet();
        List<Object> rm = new ArrayList<>();
        for (Entry<K, V> entry : entries) {
            Boolean bool = checkExpiry(entry.getKey(), false);
            if (bool)
                rm.add(entry.getKey());
            // value相等,并且key没有过期
            if (value.equals(entry.getValue()) && !bool) {
                flag = Boolean.TRUE;
                break;
            }
        }
        for (Object key : rm) {
            timeMap.remove(key);
            super.remove(key);
        }
        return flag;
    }
 
    @Override
    public Collection<V> values() {
        delAllExpiry();
        return super.values();
    }
 
    /**
     * 是否过期 true代表已过期
     * @return
     */
    private boolean checkExpiry(Object key, boolean isRemove){
        if(!timeMap.containsKey(key)){
            return Boolean.TRUE;// 没有,代表已过期
        }
        long expiryTime = timeMap.get(key);
        boolean flag = System.currentTimeMillis() > expiryTime;
        if(flag && isRemove){
            super.remove(key);
            timeMap.remove(key);
        }
        return flag;
    }

    // 删除所有已过期的key
    private void delAllExpiry() {
        Set<K> keySet = super.keySet();
        List<Object> rm = new ArrayList<>();
        for (K key : keySet) {
            Boolean bool = checkExpiry(key, false);
            if (bool)
                rm.add(key);
        }
        for (Object key : rm) {
            timeMap.remove(key);
            super.remove(key);
        }
    }
}

参考:https://blog.csdn.net/qq_16504067/article/details/125788162

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值