Java 仅包含最新条目的HashMap

Java 仅包含最新条目的HashMap,java,data-structures,collections,hashmap,Java,Data Structures,Collections,Hashmap,我最近接受了一次采访,采访者让我创建一个最多有7个键/值对的HashMap。如果添加了第八个密钥/值对,则应删除第一个密钥/值对,并插入第八个密钥/值对以替换它,以此类推 解决这个问题的好策略是什么?Java标准库包含一个名为的类型,它或多或少实现了您希望在这里实现的功能。它类似于常规的HashMap,只是它跟踪元素插入的顺序。如果您定义了一个子类并覆盖了受保护的方法,那么LinkedHashMap将自动逐出旧的元素,并按照您希望的时间表将它们替换为新的元素 另一方面,如果您想自己构建这样的东西

我最近接受了一次采访,采访者让我创建一个最多有7个键/值对的
HashMap
。如果添加了第八个密钥/值对,则应删除第一个密钥/值对,并插入第八个密钥/值对以替换它,以此类推


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

Java标准库包含一个名为的类型,它或多或少实现了您希望在这里实现的功能。它类似于常规的
HashMap
,只是它跟踪元素插入的顺序。如果您定义了一个子类并覆盖了受保护的方法,那么
LinkedHashMap
将自动逐出旧的元素,并按照您希望的时间表将它们替换为新的元素

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

也就是说,上述策略最适合于相当大的映射(例如,100个键/值对或更多)。如果您只需要存储七个键/值对,那么几乎可以肯定,将所有元素都放入一个未排序的数组中,并通过检查每个元素来迭代元素以找到您要查找的元素会更快。:-)


最后,有趣的事实是:你设计的东西有时被称为。它们广泛用于硬件和软件。

使用和覆盖创建数据结构,例如:

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; 
    }
}
用法示例:

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());
    }
}
[2, 3, 4]
输出:

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());
    }
}
[2, 3, 4]

您需要一个自定义结构,HashMap不支持这个。您需要HashMap的具体原因是什么?有了这么少的元素,一个循环数组将产生相同甚至更好的性能(
contains
在大约7个元素之后使用哈希开始更快,而不是在数组中进行标准搜索)HashMap没有被订购有人在采访中问到这一点,他只想要hashmap,虽然这可以在概念上实现,而不需要很多额外的步骤,但hashmap,从设计角度看,以及它是如何在Java中实现的,并不支持这一点。它不受尺寸限制,也不需要订购。此外,JavasHashMap并不总是由具有基于哈希的索引的数组表表示。它根据各种因素将表示转换为红/黑树。在口头面试中,
HashMap
和“HashMap”听起来是一样的。Java确实支持一种既支持哈希访问又支持LRU缓存重放的结构。@user7我相信这里列出的所有解决方案都可以支持这一点。带有线程链接列表的
LinkedHashMap
HashMap
自然都能做到这一点。基于数组的方法可以通过跟踪要覆盖的下一个插槽的索引来实现这一点,这样就不需要显式地移动元素。是的。没有必要向上移动。我添加了一条评论,认为新元素需要在最后添加。@templatetypedef这就是
ArrayDeque
免费提供给您的内容。正如一个小提示:虽然这可能确实是一个优雅的解决方案,但我认为这并不是面试官真正期待的。它非常具体,采访可能更多的是关于如何在概念上做到这一点,一开始并不是真的在谈论Javas HashMap类。我在去年的几次采访中被问到这个问题:)一些采访者会继续问下一个问题,或者要求你提出你自己的LinkedList实现。我不知怎的错过了问题中说它必须是
Map
的部分对
int
…@Holger有额外的方法,你就这样吧。