简体   繁体   English

HashMap只包含最近的条目

[英]HashMap with only most recent entries

I recently had an interview where the interviewer asked me to create a HashMap that has a maximum of 7 key/value pairs. 我最近接受了采访,采访员要求我创建一个最多有7个键/值对的HashMap If an 8th key/value pair is added, the first key/value pair should be removed and the eighth inserted to replace it, etc. 如果添加了第8个键/值对,则应删除第一个键/值对,插入第八个键/值对以替换它,等等。

What's a good strategy for solving this problem? 什么是解决这个问题的好策略?

The Java standard libraries contains a type called LinkedHashMap that does more or less what you're hoping to do here. Java标准库包含一个名为LinkedHashMap的类型,它或多或少地执行了您希望在此处执行的操作。 It's like a regular HashMap except that it keeps track of the order in which elements were inserted. 它就像一个常规的HashMap除了它跟踪插入元素的顺序。 If you define a subclass and override the removeEldestEntry protected method, then the LinkedHashMap will automagically evict old elements and replace them with new ones on whatever schedule you'd like. 如果您定义一个子类并覆盖removeEldestEntry受保护的方法,那么LinkedHashMap将自动驱逐旧元素,并在您希望的任何计划中用新元素替换它们。

On the other hand, if you'd like to build something like this on your own, you're probably looking for something like a hash table that has a doubly-linked-list threaded through the elements. 另一方面,如果你想自己构建这样的东西,你可能正在寻找像哈希表这样的东西,它具有穿过元素的双链表。 Whenever you insert an element, you append it to the linked list, and then, if there are too many elements, you remove the first element. 每当插入元素时,都会将其附加到链接列表,然后,如果元素太多,则删除第一个元素。 I'll leave the details of how to do deletions, etc. up to you. 我将详细介绍如何删除等等。

That being said, the above strategies are best-suited for fairly large maps (say, a hundred key/value pairs or more). 话虽如此,上述策略最适合相当大的地图(例如,一百个键/值对或更多)。 If you only need to store seven key/value pairs, then it's almost certainly faster to just throw everything in an unsorted array and iterate over the elements to find the one you're looking for by just checking each. 如果你只需要存储七个键/值对,那么几乎可以肯定的是,只需将所有内容放入一个未排序的数组中,然后通过检查每个元素来迭代元素以找到你正在寻找的那个。 :-) :-)

And finally, fun fact: what you're designing is sometimes called an LRU cache . 最后,有趣的事实是:您正在设计的内容有时称为LRU cache These are used extensively in hardware and software. 它们广泛用于硬件和软件中。

Make a data structure using LinkedHashMap and override removeEldestEntry ie something like this: 使用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; 
    }
}

Alternatively, if you are not allowed to use standard libraries or you are using a language that does not have an ordered dictionary structure like Java/Python you can use a Hashtable + and a DoubleEndedLinkedList that you can define yourself and achieve the same thing or use a Deque : 或者,如果您不允许使用标准库,或者您使用的语言不具有Java / Python之类的有序字典结构,则可以使用Hashtable +和DoubleEndedLinkedList ,您可以自己定义并实现相同的功能或使用Deque

  • Time complexity: O(1) for both put and get. 时间复杂度:对于put和get都是O(1)
  • Space complexity: O(capacity) . 空间复杂度: O(capacity)

Although you have to write a lot more code. 虽然你必须编写更多代码。


Generic version as per @Holger 's request : 根据@Holger的请求的通用版本

import java.util.LinkedHashMap;
import java.util.Map;

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

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

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

Example Usage: 用法示例:

class Main {
    public static void main(String[] args) {
        CustomHashMap map = new CustomHashMap(3);
        map.put(1, null);
        map.put(2, null);
        map.put(3, null);
        map.put(4, null);
        System.out.println(map.keySet());
    }
}

Output: 输出:

[2, 3, 4]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM