Java Weak Hash Map - необходимо удалить запись из-за слабости значения, а не ключа - PullRequest
7 голосов
/ 14 апреля 2011

Итак, Java WeakHashMap позволяет создать карту, записи которой удаляются, если ее ключи становятся слабыми.Но как я могу создать карту, чьи записи удаляются, когда значения на карте становятся слабыми?Я хочу использовать карту в качестве глобальной хэш-таблицы, которая отслеживает объекты в соответствии с их идентификаторами.

ID --->  Object Address

Key ---> Value

(где ID - текстовая строка)

Iхотите, чтобы пары ключ-значение были удалены, когда адреса объектов становятся слабыми, а не строки, указывающие на них.У кого-нибудь есть мысли по этому поводу?

Ответы [ 4 ]

7 голосов
/ 14 апреля 2011

Такая карта поддерживается, например, в Гуава :

Map<..., ...> m = new MapMaker().weakValues().makeMap();
3 голосов
/ 14 апреля 2011

Почему вы хотите, чтобы вход собирался мусором? Я вижу две причины

  1. избегать утечек памяти (избегайте держать слабую ссылку, указывающую на что-либо на вашей карте)
  2. myMap.get (myKey) должен возвращать ноль, если объект был собран мусором.

Решение использовать обычный HashMap:

Map<String, WeakReference<Object>>

тогда, если 2) является единственной проблемой, просто используйте myMap.get (myKey) .get ()

Если вам нужно также удалить записи, взгляните на этот пост , который описывает softHashMap и адаптирует его для использования слабых ссылок ...

3 голосов
/ 14 апреля 2011

API 1002 * имеет ответ:

Примечание по реализации: Объекты значений в WeakHashMap хранятся с помощью обычных сильных ссылок. Таким образом, следует позаботиться о том, чтобы объекты-значения не строго ссылались на свои собственные ключи, прямо или косвенно, так как это предотвратит сброс ключей. Обратите внимание, что объект значения может косвенно ссылаться на свой ключ через сам WeakHashMap; то есть объект значения может строго ссылаться на некоторый другой ключевой объект, чей связанный объект значения, в свою очередь, строго ссылается на ключ первого объекта значения. Один из способов справиться с этим - обернуть сами значения в WeakReferences перед вставкой, как в: m.put(key, new WeakReference(value)), а затем разворачивается при каждом получении.

1 голос
/ 14 апреля 2011

Вы можете делать то, что делает WeakHashMap, но со значениями вместо ключей: оберните свои значения в WeakReferences и свяжите их с ReferenceQueue, хранящимся на карте. Каждый раз, когда к карте обращаются, проверьте ReferenceQueue, чтобы увидеть, было ли что-либо добавлено, и, если оно есть, удалите его запись с карты. Вам нужно создать подкласс WeakReference, который содержит ключ, чтобы вы знали, какую запись удалить. Вам также нужно будет добавить проверку к методам, которые запрашивают карту (get и containsKey, методы итератора и т. Д.), Чтобы проверить, действительно ли извлеченная ссылка WeakReference содержит значение (не забудьте либо запретить нулевые значения, либо использовать специальный объект sentinel для представлять их).

...