私はJavaでソフト参照と弱参照を処理することに慣れていませんが、メモリがいっぱいになるとhdd機能にオーバーフローを提供するGemfireのようなデータグリッドを処理するために使用されているため、原則を理解しています。おそらくソフト参照などを使用しています。推測してみて。
Guavaで私が理解していないのは、キーをソフト/ウィークにし、値をソフト/ウィークにするメソッドを提供することです。
たとえば、ソフト以外の値を使用してソフトキーを作成する意味は何でしょうか。つまり、ソフト参照が収集され始めると、そのキーでエントリを見つけることができなくなります。それでは、なぜ値をマップに残したいのでしょうか。
誰かが私たちにいくつかのユースケースを与えることができますか?
- 弱いキー/ソフト値
- 弱いキー/通常の値
- ソフトキー/弱値
- ソフトキー/通常値
ありがとう
編集 私の質問が十分に正確かどうかわからないので、知りたいのは次のとおりです。
- キーが収集されると(弱い/ソフト)、値はどうなりますか(弱い/ソフトではない)
- 値が収集されると(弱い/柔らかい)、キーはどうなりますか
- 欠落している部分(キーまたは値)を持つエントリはキャッシュに保持されますか?
- そして、そのようなエントリをキャッシュに残したい場合のユースケースはありますか。
編集: Kevin Bourillonの回答で説明したように、最後に、ソフトキーを使用しても意味がない理由を理解したと思います。理由は次のとおりです。
static class KeyHolder {
final private String key;
public KeyHolder(String key) {
this.key = key;
}
public String getKey() {
return key;
}
@Override
public boolean equals(Object o) {
KeyHolder that = (KeyHolder)o;
boolean equality = this.getKey().equals(that.getKey());
return equality;
}
@Override
public int hashCode() {
return key != null ? key.hashCode() : 0;
}
@Override
public String toString() {
return "KeyHolder{" +
"key='" + key + '\'' +
'}';
}
}
public static void main(String[] args) {
System.out.println("TESTING WEAK KEYS");
testMap( new MapMaker().weakKeys().<KeyHolder,String>makeMap() );
System.out.println("\n\n");
System.out.println("TESTING SOFT KEYS");
testMap(new MapMaker().softKeys().<KeyHolder, String>makeMap());
System.out.println("\n\n");
System.out.println("TESTING SOFT REFERENCES");
KeyHolder key1 = new KeyHolder("toto");
KeyHolder key2 = new KeyHolder("toto");
SoftReference<KeyHolder> softRef1 = new SoftReference<KeyHolder>(key1);
SoftReference<KeyHolder> softRef2 = new SoftReference<KeyHolder>(key2);
System.out.println( "equals keys? " + key1.equals(key2) );
System.out.println( "equals ref? " + softRef1.equals(softRef2) );
}
private static void testMap(Map<KeyHolder,String> map) {
KeyHolder strongRefKey = new KeyHolder("toto");
KeyHolder noStrongRefKey = new KeyHolder("tata");
map.put(strongRefKey,"strongRef");
map.put(noStrongRefKey,"noStrongRefKey");
// we replace the strong reference by another key instance which is equals
// this could happen for exemple in case of serialization/deserialization of the key
noStrongRefKey = new KeyHolder("tata");
System.gc();
System.out.println( "strongRefKey = " + map.get(strongRefKey) );
System.out.println( "noStrongRefKey = " + map.get(noStrongRefKey) );
System.out.println( "keyset = " + map.keySet() );
}
このコードは次の出力を生成します。
TESTING WEAK KEYS
strongRefKey = strongRef
noStrongRefKey = null
keyset = [KeyHolder{key='toto'}]
TESTING SOFT KEYS
strongRefKey = strongRef
noStrongRefKey = null
keyset = [KeyHolder{key='tata'}, KeyHolder{key='toto'}]
TESTING SOFT REFERENCES
toto == toto -> true
equals keys? true
equals ref? false
ご覧のとおり、(非推奨の)ソフトキーマップでは、「tata」を含むKeyHolderがマップにまだ存在しています。ただし、新しく作成されたキーを使用してエントリを見つけることができないことに注意してください。 " new KeyHolder("tata");
"
これは、キーが有意義に等しいためですが、EqualsメソッドがGuavaでオーバーライドされていないため、それらの周りの参照ラッパーは等しくありません。
この場合、はい、softKeysは何の意味もありません。それを取得できるようにするには、そのキーへのID参照を絶対に保持する必要があるからです。