Java Map 与 TimeToLive 与每个键/值对相关联

标签 java hashmap ttl

最近,我(在一次采访中)被要求设计 HashMap ,并将 TTL 与每个键相关联。我使用下面给出的类似方法完成了它,但根据他的说法,这不是一个好方法,因为这需要在整个 map 上迭代,如果 map 大小以百万为单位,那么这将是一个瓶颈。

有没有更好的方法来做同样的事情?此外,他只关心线程在后台继续运行,尽管下一个 TTL 是在几个小时之后。

class CleanerThread extends Thread {
    @Override
    public void run() {
        System.out.println("Initiating Cleaner Thread..");
        while (true) {
            cleanMap();
            try {
                Thread.sleep(expiryInMillis / 2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void cleanMap() {
        long currentTime = new Date().getTime();
        for (K key : timeMap.keySet()) {
            if (currentTime > (timeMap.get(key) + expiryInMillis)) {
                V value = remove(key);
                timeMap.remove(key);
                System.out.println("Removing : " + sdf.format(new Date()) + " : " + key + " : " + value);
            }
        }
    }
}

最佳答案

最好使用LinkedHashMap,这样您就可以保留插入顺序。事实上,LinkedHashMap 是从 HashMap 扩展而来的。如果运行线程是问题,那么您可以通过扩展 LinkedHashMap 来创建映射的自定义实现。在类内部,重写 get 方法。

编辑:基于onkar的评论。最好重写 get 而不是 put,因为这会阻止检索过期的项目。

public class MyLinkedHashMap<K> extends LinkedHashMap<K, Date> {
    
    private static final long expiryTime = 100000L;
    private long currentOldest = 0L;

    @Override
    public Date get(Object key) {
        long currentTime = new Date().getTime();
        if ((currentOldest > 0L) && (currentOldest + expiryTime) < currentTime) {
            // even the oldest key has not expired.
            return super.get(key);
        }

        Iterator<Map.Entry<K, Date>> iter = this.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<K, Date> entry = iter.next();
            long entryTime = entry.getValue().getTime();
            if (currentTime >= entryTime + expiryTime) {
                iter.remove();
            } else {
                // since this is a linked hash map, order is preserved.
                // All the elements after the current entry came later.
                // So no need to check the remaining elements if the current is not expired.
                currentOldest = entryTime;
                break;
            }
        }

        return super.get(key);
    }
}

关于Java Map 与 TimeToLive 与每个键/值对相关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66615154/

相关文章:

java - java中的位运算符

java - 使用二维数组填充行和单元格时遇到困难

java - 在java中返回多个map<string,string>

ios - 在 ios 上跳跟踪 ttl reciveform

python - 用 Python 写一个 TTL 装饰器

phpredis 函数 mSet 与 ttl

java - Vaadin 容器过滤器选择空字段

java - Mybatis log4j如何配置log4j以将sql日志打印到文件

java - 使用 Gson 序列化具有非原始值的对象的 ArrayList?

java - 迭代 HashMap 的两种方法有什么区别