HashMap仅包含最新条目

时间:2019-07-23 18:26:30

标签: java data-structures collections hashmap

我最近进行了一次采访,采访者要求我创建一个HashMap,最多包含7个键/值对。如果添加了第8个键/值对,则应删除第一个键/值对,并插入第8个键/值对,以此类推。

解决这个问题的好策略是什么?

2 个答案:

答案 0 :(得分:5)

Java标准库包含一个名为LinkedHashMap的类型,它或多或少地完成了您希望在此处执行的操作。就像常规的HashMap一样,除了它跟踪插入元素的顺序。如果定义一个子类并覆盖受removeEldestEntry保护的方法,则LinkedHashMap将自动撤回旧元素,并按您希望的时间表将它们替换为新元素。

另一方面,如果您想自己构建类似的内容,则可能正在寻找像哈希表这样的东西,该哈希表具有穿过元素的双链表。每当插入元素时,都将其追加到链接列表中,然后,如果元素太多,则删除第一个元素。我将把删除操作等细节留给您。

话虽如此,以上策略最适合于相当大的地图(例如,一百个键/值对或更多)。如果您只需要存储七个键/值对,那么几乎可以肯定的是,将所有内容都放入一个未排序的数组中,并通过检查每个元素来遍历元素以查找所需的元素,这样会更快。 :-)

最后,一个有趣的事实:您设计的内容有时称为LRU cache。这些已广泛用于硬件和软件。

答案 1 :(得分:3)

使用 LinkedHashMap 创建数据结构并覆盖 removeEldestEntry ,即类似这样的内容:

import java.util.LinkedHashMap;

class CustomHashMap extends LinkedHashMap<Integer, Integer>{
    private int capacity;

    public CustomHashMap(int capacity) {
        super(capacity, 0.75F, true);
        this.capacity = capacity;
    }

    public int get(int key) {
        return super.getOrDefault(key, -1);
    }

    public void put(int key, int value) {
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity; 
    }
}

或者,如果不允许使用标准库,或者使用的语言没有Java / Python等有序词典结构,则可以使用Hashtable +和DoubleEndedLinkedList可以定义自己并实现相同的目标:

  • 时间复杂度: O(1)(用于放置和获取)。
  • 空间复杂度: O(capacity)

尽管您必须编写更多代码。