Чому існує WeakHashMap, але немає WeakSet?


76

Від Дж. Блоха

... джерелом витоків пам'яті є слухачі ... Найкращий спосіб забезпечити, щоб зворотні виклики були негайно зібраним сміттям, - це зберігати лише слабкі посилання на них, наприклад, зберігаючи їх лише як ключі в WeakHashMap .

Отже, чому у фреймворку Java Collections немає жодного WeakSet ?


1
Стасе, ти можеш прийняти правильну відповідь Марта замість Мартина, неправильну відповідь?
toolforger

Хоча Джошуа Блок написав багато розумних порад для програмістів Java, це, здається, є жахливим винятком. Зберігання слухачів у програмі WeakHashMap"ніколи" не гарантує, що зворотні виклики - це сміття, яке збирається негайно ", а робить їх жахливо недетермінованими. Збирач сміття буде працювати лише тоді, коли недостатньо пам'яті, отже, такі слабкі слухачі можуть довгий час бовтатися і все ще виконуються , але що ще гірше, такі слухачі можуть помилково зникнути, коли вони вам все ще потрібні, оскільки зараз йому потрібен насправді не пов'язані сильні посилання, щоб зберегти їх у живих.
Holger

Відповіді:


194
Set<Object> weakHashSet = Collections.newSetFromMap(
        new WeakHashMap<Object, Boolean>());

Як видно з Collections.newSetFromMapдокументації, передача a WeakHashMapдля отримання Set.


4
насправді будь-який набір у колекції Java містить карту для зберігання.
березень

4
Так, але чому немає спеціального класу для таких речей?
Stan Kurilin

14
Легко уявити, чому супровідники java.util, можливо, захотіли припинити надавати подвійні версії Map і Set усього, що вони роблять, і замість цього просто надали newSetFromMap () ... чи не так?
Kevin Bourrillion

24
Варто зазначити, що Collections # newSetFromMap відсутній в Android перед API 9. Хоча не складно знайти реалізацію для компіляції у вашій програмі, однак це проблема сумісності.
нмр

3
@Mike JavaDoc правильний. Зверніть увагу, що код у цій відповіді повертає набір об’єктів, а не логічні значення. newSetFromMapстворює набір типу ключів, а не значень.
kabuko

14

Отже, чому в рамках колекції Java немає жодного WeakSet?

Єдина справді правильна відповідь на це - ми не можемо сказати вам, чому, тому що ми не люди, які приймали дизайнерські рішення. Тільки розробники Java знають, чому вони прийняли рішення 1 .


Хоча можуть бути обмежені випадки використання для WeakHashSet, частина філософії дизайну бібліотеки класів Java полягала в тому, щоб уникати заповнення бібліотек класів корисними класами для всіх можливих випадків використання.

Існує ряд інших бібліотек класів, які включають типи колекцій; Хорошими прикладами є колекції Apache Commons і Google Collections (він же Гуава). Однак WeakHashSetнавіть не зробив "скорочення" для бібліотек Apache та Google.

І, звичайно, ви можете використовувати Collections.newSetFromMapдля обгортання WeakHashMapекземпляра.


1 - Обговорення правильності цього рішення поза сферою дії StackOverflow. Це сайт із запитаннями та відповідями, а не дискусійний форум.


Дякую. Ймовірно, мені потрібно більше поспостерігати за іншими бібліотеками, щоб зрозуміти структуру колекції Java.
Стен Курілін

“Обмежені випадки використання WeakHashSet”? Доктор Блох дав вам дуже поширений приклад використання, як цитується у Запитанні.
Василь Бурк,

Цитата Блоха описує варіант використання для WeakHashMapnot WeakHashSet. Чи конкретно він згадує відсутність слабкого хеш-набору як проблему? Якщо ні, то ви не можете претендувати на нього як на авторитет, оскільки ви заявляєте, що це проблема. У будь-якому випадку, це питання та відповіді, а не дискусія. Я просто відповідаю на запитання ОП відповіддю, яку зазвичай дають дизайнери Java, не включаючи подібні речі. Чи погоджуєтесь ви (або ОП), це ... не суть справи.
Stephen C

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.