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

时间:2015-02-03 21:11:32

标签: java caching

通过这个问题,我的意思是:我有一个使用LinkedHashMap实现缓存的Java缓存实现。但是,我已经意识到在维护缓存时我需要一个除最近最少使用或最后插入之外的订购。但我真的很喜欢LinkedHashMap的其他功能来实现缓存,例如大小限制的地图和可自定义的removeEldestEntry方法。由于这是可能存在数万个对象的缓存,我不确定TreeMap是否足够快以构建(但我还没有测试过)。

我的最终约束是:请记住,这是在开发周期非常远的数十万行代码的现有代码库中。因此,我们无法根据需要交换新的COTS / OTS,因为需要进行大量的回归测试和返工。我们目前正在使用Java 7,Guava Release 09(哎呀!我知道......)和Apache Commons Collections 3.2.1

1 个答案:

答案 0 :(得分: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);
            }
        }
    }
}

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

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