Я не привык иметь дело с мягкими и слабыми ссылками в Java, но я понимаю принцип, поскольку я Я привык иметь дело с сетками данных, такими как Gemfire, которые обеспечивают переполнение функций жесткого диска, когда память заполнена, вероятно, используя мягкие ссылки или что-то подобное, я думаю.
Чего я не понимаю в Гуаве, так это того, что она предоставляет методы для того, чтобы сделать клавиши мягкими/слабыми и значения мягкими/слабыми.
Мне просто интересно, какой смысл создавать программные клавиши с немягкими значениями, например? Я имею в виду, когда начинают собираться мягкие ссылки, мы уже не можем найти запись по ее ключу, так почему мы хотим, чтобы значения оставались на карте?
Может ли кто-нибудь дать нам несколько вариантов использования с:
Спасибо
Изменить Я не уверен, что мой вопрос достаточно точен, поэтому я хотел бы знать следующее:
Изменить: Как обсуждалось в ответе Кевина Бурильона, наконец, я думаю, что понимаю, почему использование программных клавиш ничего не значит. И вот почему:
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
Как вы можете видеть, с (устаревшей) картой функциональных клавиш KeyHolder, содержащий «tata», все еще существует в карте.
Но обратите внимание, что я все еще не могу найти свою запись с вновь созданным ключом " new KeyHolder("tata");
"
Это потому, что мои ключи по смыслу равны, но ссылочные обертки вокруг них не равны, потому что их метод равенства не переопределен в Гуаве!
В этом случае, да, программные клавиши ничего не значат, поскольку вам абсолютно необходимо сохранить ссылку на этот ключ, чтобы иметь возможность его получить.