Warum gibt es WeakHashMap, aber kein WeakSet?

76

Von J. Bloch

Eine ... Quelle für Speicherlecks sind Listener ... Der beste Weg, um sicherzustellen, dass Rückrufe sofort gesammelt werden, besteht darin, nur schwache Verweise auf sie zu speichern, indem Sie sie beispielsweise nur als Schlüssel in einer WeakHashMap speichern .

Warum gibt es im Java Collections-Framework kein WeakSet ?

Stan Kurilin
quelle
1
Stas, kannst du Marts hochgestimmte, richtige Antwort anstelle von Martins herabgestufter, falscher Antwort akzeptieren?
Werkzeugschmied
Während Joshua Bloch viele vernünftige Ratschläge für Java-Programmierer schrieb, scheint dies eine schreckliche Ausnahme zu sein. Das Speichern von Listenern in a WeakHashMapstellt niemals „sicher, dass Rückrufe sofort gesammelt werden“, sondern macht sie schrecklich unsinnig. Der Garbage Collector wird nur ausgeführt, wenn nicht genügend Speicher vorhanden ist. Daher können solche schwachen Listener eine beliebig lange Zeit lang baumeln und immer noch ausgeführt werden. Schlimmer noch, solche Listener verschwinden möglicherweise fälschlicherweise, wenn Sie sie noch benötigen, da sie jetzt einen benötigen eigentlich nicht verwandte starke Referenz, um sie am Leben zu halten.
Holger

Antworten:

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

Wie in der Collections.newSetFromMapDokumentation zu sehen, übergeben Sie a WeakHashMap, um a zu erhalten Set.

Mart
quelle
4
Tatsächlich enthält jedes Set in der Java-Sammlung eine Karte zum Speichern.
Mart
4
Ja, aber warum gibt es keine spezielle Klasse für solche Sachen?
Stan Kurilin
14
Es ist leicht vorstellbar, warum die Betreuer von java.util möglicherweise aufhören wollten, Dual Map- und Set-Versionen von allem, was sie tun, bereitzustellen, und sich stattdessen dafür entschieden haben, stattdessen nur newSetFromMap () bereitzustellen ... nicht wahr?
Kevin Bourrillion
24
Es ist erwähnenswert, dass Collections # newSetFromMap in Android vor API 9 fehlt. Es ist zwar nicht schwierig, eine Implementierung zum Kompilieren in Ihre App zu finden, aber es ist ein Kompatibilitätsproblem.
nmr
3
@Mike Das JavaDoc ist korrekt. Beachten Sie, dass der Code in dieser Antwort eine Reihe von Objekten und keine Booleschen Werte zurückgibt. newSetFromMapErstellt einen Satz des Schlüsseltyps, nicht der Werte.
Kabuko
14

Warum gibt es kein WeakSet im Java Collection Framework?

Die einzig wirklich richtige Antwort darauf ist, dass wir Ihnen nicht sagen können, warum, weil wir nicht die Leute sind, die die Designentscheidungen getroffen haben. Nur die Java-Designer wissen, warum sie die Entscheidung getroffen haben 1 .


Obwohl es möglicherweise nur begrenzte Anwendungsfälle für gibt WeakHashSet, bestand ein Teil der Designphilosophie der Java-Klassenbibliothek darin, zu vermeiden, dass die Klassenbibliotheken für alle möglichen Anwendungsfälle mit Dienstprogrammklassen gefüllt werden.

Es gibt eine Reihe anderer Klassenbibliotheken, die Sammlungstypen enthalten. Apache Commons Collections und Google Collections (auch bekannt als Guava) sind gute Beispiele. Allerdings WeakHashSethat noch nicht einmal der Schnitt für die Apache- und Google-Bibliotheken gemacht.

Und natürlich können Sie Collections.newSetFromMapeine WeakHashMapInstanz umschließen.


1 - Die Debatte über die Richtigkeit dieser Entscheidung ist für StackOverflow nicht möglich. Dies ist eine Q & A-Site, kein Diskussionsforum.

Stephen C.
quelle
Vielen Dank. Wahrscheinlich muss ich mehr Beobachtungsarbeit über andere Bibliotheken leisten, um das Java Collection Framework zu verstehen.
Stan Kurilin
"Eingeschränkte Anwendungsfälle für WeakHashSet"? Dr. Bloch gab Ihnen einen sehr häufigen Anwendungsfall, wie in der Frage zitiert.
Basil Bourque
Das Bloch-Zitat beschreibt einen Anwendungsfall für WeakHashMapnicht WeakHashSet. Erwähnt er ausdrücklich das Fehlen eines schwachen Hash-Sets als Problem? Wenn nicht, können Sie ihn nicht als Autorität für Ihre Behauptung beanspruchen, dass es sich um ein Problem handelt. Auf jeden Fall ist dies eine Frage und Antwort, keine Debatte. Ich beantworte lediglich die Frage des OP mit der Antwort, die die Java-Designer routinemäßig geben, wenn sie solche Dinge nicht berücksichtigen. Ob Sie (oder das OP) zustimmen, ist ... nebensächlich.
Stephen C