LinkedHashMap(或类似的东西)可以使用自定义排序吗?



这个问题的意思是:我有一个使用LinkedHashMap来实现缓存的Java缓存实现。 但是,我开始意识到,在维护缓存时,除了"最近最少使用"或"上次插入"之外,我还需要排序。 但我真的很喜欢LinkedHashMap用于实现缓存的其他功能,例如大小受限的地图和可自定义的removeEldestEntry方法。 由于这是可能包含数万个对象的缓存,因此我不确定TreeMap是否足够快,可以构建(但我还没有对此进行测试)。

我的最后一个约束是:请记住,这是在数十万行代码的现有代码库中,该代码库在开发周期中非常远。 因此,我们不能根据需要交换新的 COTS/OTS,因为需要大量的回归测试和返工。 我们目前正在使用 Java 7,番石榴发布 09(哎哟!我知道...和 Apache 共享资源集合 3.2.1

不幸的是,

没有简单的方法可以做到这一点。如果你看一下LinkedHashMap的源代码,你会发现这个机制非常简单:任何时候访问一个项目时,它都会被移动到(私有)链表的末尾。然后,头部的项目是最近访问最少的项目。它很有效,但不是特别复杂。

一种选择是扩展类以覆盖用于选择要删除的项的机制。您可以通过覆盖addEntry来执行更复杂的操作,例如删除一个或多个您知道不会再次访问的项目来执行此操作。

这样的事情可能是可能的:

class MyHashMap extends LinkedHashMap<String, String> {
    LinkedList<String> lowPriorityItems = new LinkedList<>();
    @Override
    void addEntry(int hash, String key, String value, int bucketIndex) {
        if (isLowValue(key)) {
            lowPriorityItems.add(key);
        }
        if (size >= threshold) {
            if (lowPriorityItems.isEmpty()) {
                super.addEntry(hash, key, value, bucketIndex);
            else {
                removeAll(lowPriorityItems);
                lowPriorityItems.clear();
                super.createEntry(hash, key, value, bucketIndex);
            }
        }
    }
}

这只是一个例子,但它基本上可以通过在您接近阈值时定期删除缓存中的项目来工作。如果缓存中没有低优先级项目,则回退到使用默认方法。

希望您能看到如何使其更加复杂以满足您的需求。

最新更新