java带有效期的map

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011534095/article/details/54091337


在日常工作中有很多场景需要一个类似于MC或者redis这种可以设置过期时间的K,V存储方式,但是使用MC或者redis又有点大材小用,最理想的就是希望map有这个功能

ExpiryMap继承至HashMap 重写了所有对外的方法,对每个key值都设置了有效期
 ———————————————— 
 

package com.aiggo.common.util;
 
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
/**
 * 
 * @Description: 带有效期map 简单实现 实现了基本的方法
 * @author: qd-ankang
 * @date: 2016-11-24 下午4:08:46
 * @param <K>
 * @param <V>
 */
public class ExpiryMap<K, V> extends HashMap<K, V>{
 
	private static final long serialVersionUID = 1L;
	
	/**
	 * default expiry time 2m
	 */
	private long EXPIRY = 1000 * 60 * 2;
	
	private HashMap<K, Long> expiryMap = new HashMap<>();
	
	public ExpiryMap(){
		super();
	}
	public ExpiryMap(long defaultExpiryTime){
		this(1 << 4, defaultExpiryTime);
	}
	public ExpiryMap(int initialCapacity, long defaultExpiryTime){
		super(initialCapacity);
		this.EXPIRY = defaultExpiryTime;
	}
	public V put(K key, V value) {
		expiryMap.put(key, System.currentTimeMillis() + EXPIRY);
        return super.put(key, value);
    }
	 public boolean containsKey(Object key) {
	     return !checkExpiry(key, true) && super.containsKey(key);
	 }
	/**
	     * @param key
	     * @param value
	     * @param expiryTime 键值对有效期 毫秒
	     * @return
	 */
	public V put(K key, V value, long expiryTime) {
		expiryMap.put(key, System.currentTimeMillis() + expiryTime);
        return super.put(key, value);
    }
    public int size() {
        return entrySet().size();
    }
    public boolean isEmpty() {
        return entrySet().size() == 0;
    }
    public boolean containsValue(Object value) {
    	if (value == null) return Boolean.FALSE;
    	Set<java.util.Map.Entry<K, V>> set = super.entrySet();
    	Iterator<java.util.Map.Entry<K, V>> iterator = set.iterator();
    	while (iterator.hasNext()) {
			java.util.Map.Entry<K, V> entry = iterator.next();
			if(value.equals(entry.getValue())){
				if(checkExpiry(entry.getKey(), false)) {
					iterator.remove();
					return Boolean.FALSE;
				}else return Boolean.TRUE;
			}
		}
    	return Boolean.FALSE;
    }
    public Collection<V> values() {
    	
    	Collection<V> values = super.values();
    	
    	if(values == null || values.size() < 1) return values;
    	
    	Iterator<V> iterator = values.iterator();
    	
    	while (iterator.hasNext()) {
    		V next = iterator.next();
			if(!containsValue(next)) iterator.remove();
		}
        return values;
    }
    public V get(Object key) {
        if (key == null)
            return null;
        if(checkExpiry(key, true))
        	return null;
        return super.get(key);
    }
    /**
     * 
    	 * @Description: 是否过期 
         * @param key
         * @return null:不存在或key为null -1:过期  存在且没过期返回value 因为过期的不是实时删除,所以稍微有点作用
     */
    public Object isInvalid(Object key) {
        if (key == null)
            return null;
        if(!expiryMap.containsKey(key)){
    		return null;
    	}
    	long expiryTime = expiryMap.get(key);
    	
    	boolean flag = System.currentTimeMillis() > expiryTime;
    	
    	if(flag){
    		super.remove(key);
        	expiryMap.remove(key);
        	return -1;
    	}
        return super.get(key);
    }
    public void putAll(Map<? extends K, ? extends V> m) {
    	 for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
    		 	expiryMap.put(e.getKey(), System.currentTimeMillis() + EXPIRY);
    	 super.putAll(m);
    }
    public Set<Map.Entry<K,V>> entrySet() {
    	Set<java.util.Map.Entry<K, V>> set = super.entrySet();
    	Iterator<java.util.Map.Entry<K, V>> iterator = set.iterator();
    	while (iterator.hasNext()) {
			java.util.Map.Entry<K, V> entry = iterator.next();
			if(checkExpiry(entry.getKey(), false)) iterator.remove();
		}
    	
    	return set;
    }
    /**
     * 
    	 * @Description: 是否过期 
         * @author: qd-ankang
         * @date: 2016-11-24 下午4:05:02
         * @param expiryTime true 过期
         * @param isRemoveSuper true super删除
         * @return
     */
    private boolean checkExpiry(Object key, boolean isRemoveSuper){
    	
    	if(!expiryMap.containsKey(key)){
    		return Boolean.FALSE;
    	}
    	long expiryTime = expiryMap.get(key);
    	
    	boolean flag = System.currentTimeMillis() > expiryTime;
    	
    	if(flag){
    		if(isRemoveSuper)
    			super.remove(key);
        	expiryMap.remove(key);
    	}
    	return flag;
    }
    public static void main(String[] args) throws InterruptedException {
		
    	ExpiryMap<String, String> map = new ExpiryMap<>(10);
    	map.put("test", "ankang");
    	map.put("test1", "ankang");
    	map.put("test2", "ankang", 3000);
    	System.out.println("test1" + map.get("test"));
    	Thread.sleep(1000);
    	System.out.println("isInvalid:" + map.isInvalid("test"));
    	System.out.println("size:" + map.size());
    	System.out.println("size:" + ((HashMap<String, String>)map).size());
    	for (Map.Entry<String, String> m : map.entrySet()) {
    		System.out.println("isInvalid:" + map.isInvalid(m.getKey()));
    		map.containsKey(m.getKey());
			System.out.println("key:" + m.getKey() + "     value:" + m.getValue());
		}
    	System.out.println("test1" + map.get("test"));
    	
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值