支持基于最近访问的项目的有效排除策略的数据结构

时间:2018-10-08 17:49:44

标签: java data-structures

我需要一个数据结构,以支持最长时间前被请求的物料的最有效的排除策略。例如,我有一些不时被要求的物品。当我的内存不足时,我想踢出数据结构(哈希图)中最旧的项。

我在考虑像Queue这样的FIFO ds smth,但是我不确定如何处理这种情况:

  

-> a b c d a->

a是最旧和最新的项目。如果再次添加“ a”,我需要搜索整个队列以将其删除。这是非常低效的,但是我想不出任何有效的方式来做到这一点。也许某种树形结构将访问最少的树形结构放在顶部?

Java中是否已经有这种数据结构的实现?

2 个答案:

答案 0 :(得分:3)

LinkedHashMap是您所追求的结构。来自the docs

  

提供了一个特殊的构造函数来创建链接的哈希映射,该哈希映射的迭代顺序是其条目的最后访问顺序(从最近的访问到最近的访问)(访问顺序)。这种映射非常适合构建LRU缓存。

所以您应该只使用appropriate constructor

Map<K, V> map = new LinkedHashMap<>(CAPACITY, LOAD_FACTOR, true);

boolean参数确定映射是访问顺序还是插入顺序true表示访问顺序。

此外,如果希望将地图用作LRU缓存,则可以创建自己的类,该类扩展LinkedHashMap并覆盖removeEldestEntry方法。再次,从文档:

  

可以重写removeEldestEntry(Map.Entry)方法,以强加一项策略,以便在向地图添加新映射时自动删除陈旧的映射。

这意味着您可以为缓存创建自己的类:

public class Cache<K, V> extends LinkedHashMap<K, V> {

    private static final int MAX_ENTRIES = 100;

    public Cache() {
        super(SOME_INITIAL_CAPACITY, SOME_LOAD_FACTOR, true);
    }

    protected boolean removeEldestEntry(Entry<K, V> entry) {
        return size() > MAX_ENTRIES;
    }
}

用法:

Map<K, V> map = new Cache<>();

答案 1 :(得分:2)

编辑:LinkedHashMap对此具有内置功能,请参见其他答案。

您可以包装LinkedHashSet(或LinkedHashMap,具体取决于您的用例),并在访问时重新插入项目,将它们移到末尾。如果内存不足,请从前端开始删除。

class LruMap<K, V> {
  LinkedHashMap<K, V> map = new LinkedHashMap<>()

  V get(K key) {
    V result = map.remove(key);
    map.put(key, result);
    return result;
  }

  void put(K key, V value) {
    map.put(key, value);
  }

  void removeEldest() {
    if (map.size() > 0) {
      map.remove(map.keySet().iterator().next());
    }
  }
}