删除LinkedHashMap中除循环以外的前半部分的条目



我打算使用Hashtable,但一些现有的答案说只有LinkedHashMap保留插入顺序。因此,我似乎可以通过entrieskeys属性获得插入顺序。

我的问题是,当映射有n个元素时,如果我想删除前n/2个元素,是否有比循环通过keys并反复调用remove(key)更好的方法?也就是像这样的

val a = LinkedHashMap<Int, Int>();
val n = 10;
for(i in 1 .. n)
{
a[i] = i*10;
}
a.removeRange(0,n/2);

不是

val a = LinkedHashMap<Int, Int>();
val n = 10;
for(i in 1 .. n)
{
a[i] = i*10;
}
var i = 0;
var keysToRemove= ArrayList<Int>();
for(k in a.keys)
{
if(i >= n/2)
break;
else
i++
keysToRemove.add(k);
}
for(k in keysToRemove)
{
a.remove(k);
}

这样做的目的是我将映射用作缓存,当缓存已满时,我希望清除最老的那一半条目。我不必使用LinkedHashMap,只要我可以:

  • 使用键查找值,高效。
  • 一次删除一系列条目。

类中没有方法可以实现这一点。源代码没有对键或项的范围进行任何操作。由于链接是建立在HashMap逻辑之上的,单个条目仍然必须通过散列键查找来单独找到以删除它们,因此在LinkedHashMap中删除范围的速度不能更快,这与LinkedList与ArrayList的类比不同。

对于更简单的代码,这相当于你所做的:

a.keys.take(a.size / 2).forEach(a::remove)

如果你不想为缓存集使用库,LinkedHashSet的设计使你可以通过子类化轻松地构建自己的缓存集。例如,当添加超过一定集合大小的元素时,一个基本的方法只是删除最老的条目:

class CacheHashMap<K, V>(private var maxSize: Int): LinkedHashMap<K, V>() {
override fun removeEldestEntry(eldest: MutableMap.MutableEntry<K, V>?): Boolean =
size == maxSize
}

同样,如果您在构造函数调用中设置accessOrder为true,它将按最近使用的条目排序,这可能比插入顺序更适合您的情况。

编辑:对不起,我错过了使用这个作为LRU缓存的部分,对于那个用例,TreeMap将不适合。


如果插入顺序对您来说只是偶然的,并且您想要的实际上是可比较键的实际顺序,那么您应该使用TreeMap。

但是,可能不直接支持删除一半键的特定用例。您应该找到方法来删除低于/高于某个值的键,并获得最高/最低的键。

相关内容

  • 没有找到相关文章

最新更新