类似于redis可设置过期时间的Map存储方式

借鉴网上某位大神自己封装的,继承自HashMap,重写了所有方法,对Map中的各个key值均设置了有效期,过期后移除。

public class ExpiryMap<K, V> extends HashMap<K, V> {

    private static final long serialVersionUID = 1L;

    /**

    * default expiry time 5s

    */

    private long EXPIRY = 5000;

    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;

    }

    @Override

    public V put(K key, V value) {

        expiryMap.put(key, System.currentTimeMillis() + EXPIRY);

        return super.put(key, value);

    }

    @Override

    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);

    }

    @Override

    public int size() {

        return entrySet().size();

    }

    @Override

    public boolean isEmpty() {

        return entrySet().size() == 0;

    }

    @Override

    public boolean containsValue(Object value) {

        if (value == null) {

            return Boolean.FALSE;

        }

        Set<Entry<K, V>> set = super.entrySet();

        Iterator<Entry<K, V>> iterator = set.iterator();

        while (iterator.hasNext()) {

            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;

    }

    @Override

    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;

    }

    /**

    * 获取value,如key过期则返回null

    * @param key

    * @return

    */

    @Override

    public V get(Object key) {

        if (key == null) {

            return null;

        }

        if (checkExpiry(key, true)) {

            return null;

        }

        return super.get(key);

    }

    /**

    *

    * @param key

    * @return

    */

    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);

    }

    @Override

    public void putAll(Map<? extends K, ? extends V> m) {

        for (Entry<? extends K, ? extends V> e : m.entrySet()) {

            expiryMap.put(e.getKey(), System.currentTimeMillis() + EXPIRY);

        }

        super.putAll(m);

    }

    @Override

    public Set<Entry<K, V>> entrySet() {

        Set<Entry<K, V>> set = super.entrySet();

        Iterator<Entry<K, V>> iterator = set.iterator();

        while (iterator.hasNext()) {

            Entry<K, V> entry = iterator.next();

            if (checkExpiry(entry.getKey(), false)) {

                iterator.remove();

            }

        }

        return set;

    }

    /**

    *

    * @param key

    * @param isRemoveSuper

    * @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<>();

        map.put("key1", "hello");

        map.put("key2", "world", 8000);

        System.out.println("key1==" + map.get("key1"));

        Thread.sleep(6000);

        System.out.println("key1==" + map.get("key1"));

        System.out.println("key2==" + map.get("key2"));

        Thread.sleep(6000);

        System.out.println("key2==" + map.get("key2"));

    }

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容