【问题标题】:LinkedHashMap removeEldestEntry and Overriding RemoveLinkedHashMap removeEldestEntry 和覆盖 Remove
【发布时间】:2016-02-03 16:00:56
【问题描述】:

我有一个扩展LinkedHashMap 的类,我将其用作缓存。这个缓存有一个属性,它定义了缓存允许存储的最大字节大小。我粗略估计了我存储的对象的大小。

我覆盖put,以便更新缓存当前存储的总大小。

我还覆盖 remove 以从总数中减去我已删除的对象的大小。

目前,我正在检查是否需要从缓存中删除陈旧的条目以释放空间,以便在 put 方法中添加新值,但是我想将此功能移动到removeEldestEntry 方法。

我遇到的问题是,如果我重写的removeEldestEntry 返回true,我的重写remove 方法似乎没有被调用。这会导致一个问题,即当removeEldestEntry 删除过时的条目时,我当前存储的大小变量没有更新。

有谁知道当removeEldestEntry 返回true 时使用什么代码路径来删除最旧的条目。我是否可以覆盖用于删除条目的方法?

LinkedHashMap 触发对removeEldestEntry 的删除时,我是否可以进行更新计算。

我知道 api 允许您在 removeEldestEntry 方法中执行实际删除,只要您之后返回 false,但是我想在执行此操作之前探索其他选项。我认为这是最后一种情况。

【问题讨论】:

    标签: java caching linkedhashmap


    【解决方案1】:

    查看source code of LinkedHashMap where removeEldestEntry is called,它没有调用remove,而是调用removeNode——在remove的默认实现中也调用了它。

    请注意,这是Fragile Base Class problem 的一个示例,其中您试图依赖基类中的实现细节(即如果removeEldestEntry 返回true,则调用remove)不是实际上是真的 - 不同之处在于它已经不是真的,而不是在未来的某个时候它变得不真实。

    您可能需要考虑围绕 LinkedHashMap 实现自己的包装类,它将很多行为委托给 LHM,但您可以在其中实现您想要的特定驱逐逻辑。

    【讨论】:

    • 谢谢安迪。 RemoveNode 是最终的,所以我无法覆盖它。我认为对我来说最好的解决方案是按照您的建议实现一个包装器,或者在 removeEldestEntry 中手动调用我的 remove 方法并按照 API 的建议从中返回 false。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多