LinkedHashMap(或类似的东西)可以使用自定义排序吗?
Can LinkedHashMap (or something like it) use a custom ordering?
关于这个问题,我的意思是:我有一个 Java 缓存实现,它使用 LinkedHashMap
to implement the cache. However, I have come to realize that I need an ordering besides Least Recently Used or Last Inserted when maintaining my cache. But I really like the other features of LinkedHashMap
for implementing a cache, such as a size-limited map and the customizable removeEldestEntry
method. Since this is a cache of potentially tens of thousands of objects, I'm not sure the TreeMap
足够快来构建(但我还没有测试过)。
我的最后一个约束是:请记住,这是在一个现有的代码库中,该代码库包含数十万行代码,并且在开发周期中已经很远了。因此,我们不能根据需要交换新的 COTS/OTS,因为需要大量的回归测试和返工。我们目前正在使用 Java 7, Guava Release 09 (Ouch! I know...) and Apache Commons Collections 3.2.1
遗憾的是,没有简单的方法可以做到这一点。如果您查看 LinkedHashMap
的源代码,您会发现该机制非常简单:任何时候访问一个项目时,它都会被移动到(私有)链表的末尾。头部的项目是最近最少访问的。它高效但不是特别复杂。
一个选项是扩展 class 以覆盖选择要删除的项目的机制。您可以通过覆盖 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);
}
}
}
}
这只是一个示例,但它基本上可以通过在接近阈值时定期删除缓存中的项目来工作。如果缓存中没有低优先级的项目,那么它会回退到使用默认方法。
希望您能看到如何使它更复杂以满足您的需求。
关于这个问题,我的意思是:我有一个 Java 缓存实现,它使用 LinkedHashMap
to implement the cache. However, I have come to realize that I need an ordering besides Least Recently Used or Last Inserted when maintaining my cache. But I really like the other features of LinkedHashMap
for implementing a cache, such as a size-limited map and the customizable removeEldestEntry
method. Since this is a cache of potentially tens of thousands of objects, I'm not sure the TreeMap
足够快来构建(但我还没有测试过)。
我的最后一个约束是:请记住,这是在一个现有的代码库中,该代码库包含数十万行代码,并且在开发周期中已经很远了。因此,我们不能根据需要交换新的 COTS/OTS,因为需要大量的回归测试和返工。我们目前正在使用 Java 7, Guava Release 09 (Ouch! I know...) and Apache Commons Collections 3.2.1
遗憾的是,没有简单的方法可以做到这一点。如果您查看 LinkedHashMap
的源代码,您会发现该机制非常简单:任何时候访问一个项目时,它都会被移动到(私有)链表的末尾。头部的项目是最近最少访问的。它高效但不是特别复杂。
一个选项是扩展 class 以覆盖选择要删除的项目的机制。您可以通过覆盖 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);
}
}
}
}
这只是一个示例,但它基本上可以通过在接近阈值时定期删除缓存中的项目来工作。如果缓存中没有低优先级的项目,那么它会回退到使用默认方法。
希望您能看到如何使它更复杂以满足您的需求。