我想唯一完美的解决方案是CacheBuilder.softKeysDelegatingEquals
按照您的建议使用番石榴。
跳到最后以获得更好的想法
也许这种解决方法可以:
- 每当你把东西放进去的时候
Cache
,就把新的SoftReference<Key>
放进你自己的HashSet
。
- 添加 a
removalListener
并Cache
从SoftReference
您的HashSet
无论如何,你不需要线程。
第二部分有点棘手,因为您获得了 aKey
并且需要删除其相应的软引用。为此,您可以将 set 替换为 a WeakHashMap<Key, SoftReference<Key>
,或者通过让您的 Key 成为equals
参考来获得 hacky:
class Key {
Key(Somedata somedata) {
this.somedata = somedata;
}
@Override public int hashCode() {
return somedata.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof Key) {
return somedata.equals(((Key) obj).somedata);
}
if (obj instanceof KeySoftReference) {
return equals(((KeySoftReference) obj).get());
}
return false;
}
@NonNull private final Somedata somedata;
}
// Hacky, never use for anything else.
class KeySoftReference extends SoftReference<Key> {
protected KeySoftReference(Key key) {
super(key);
this.hashCode = key.hashCode();
}
@Override public int hashCode() {
return hashCode;
}
@Override public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof Key) {
return ((Key) obj).equals(this);
}
if (obj instanceof KeySoftReference) {
Key key = get();
// This makes no two cleared reference equal to each other,
// That's OK as long as you never create two references to the same object.
return key!=null && key.equals(((KeySoftReference) obj).get());
}
return false;
}
private final int hashCode;
}
我想,这符合合同,但正如我所说,它是 hacky 和未经测试的。
更新
有简单的解决方案。利用
CacheBuilder.weakKeys().softValues()
并将 a 添加SoftReference<Key>
到您的Value
. 这使得密钥可以轻松访问。
如果您真的需要比较是平等的,那么您可能不走运,尽管 aWeakInterner<Key>
可能会有所帮助。