Guava CacheBuilder или MapMaker с использованием Weak/Soft

Я не привык иметь дело с мягкими и слабыми ссылками в 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");" Это потому, что мои ключи по смыслу равны, но ссылочные обертки вокруг них не равны, потому что их метод равенства не переопределен в Гуаве! В этом случае, да, программные клавиши ничего не значат, поскольку вам абсолютно необходимо сохранить ссылку на этот ключ, чтобы иметь возможность его получить.

8
задан Sebastien Lorber 15 June 2012 в 08:56
поделиться