Чому існує 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.