Default Set in Java ist leider nicht dafür ausgelegt, eine "get"-Operation zu ermöglichen, da jschreiner genau erklärt.
Die Lösungen zur Verwendung eines Iterators, um das gewünschte Element zu finden (vorgeschlagen von dacwe ) oder das Element zu entfernen und es mit aktualisierten Werten wieder hinzuzufügen (vorgeschlagen von KyleM ), könnte funktionieren, kann aber sehr ineffizient sein.
Überschreiben der Implementierung von "equals", so dass nicht-gleiche Objekte "gleich" sind, wie es korrekt in David Ogren kann leicht zu Wartungsproblemen führen.
Und die Verwendung einer Map als expliziter Ersatz (wie von vielen vorgeschlagen) macht den Code imho weniger elegant.
Wenn das Ziel darin besteht, Zugriff auf die ursprüngliche Instanz des in der Menge enthaltenen Elements zu erhalten (ich hoffe, ich habe Ihren Anwendungsfall richtig verstanden), gibt es eine weitere mögliche Lösung.
Ich persönlich hatte das gleiche Bedürfnis bei der Entwicklung eines Client-Server-Videospiels mit Java. In meinem Fall hatte jeder Client Kopien der auf dem Server gespeicherten Komponenten, und das Problem bestand darin, dass ein Client ein Objekt des Servers ändern musste.
Die Weitergabe eines Objekts über das Internet bedeutete, dass der Client ohnehin verschiedene Instanzen dieses Objekts hatte. Um diese "kopierte" Instanz mit der ursprünglichen Instanz abzugleichen, beschloss ich, Java UUIDs zu verwenden.
Also habe ich eine abstrakte Klasse UniqueItem erstellt, die automatisch jeder Instanz ihrer Unterklassen eine zufällige eindeutige ID zuweist.
Diese UUID wird von der Client- und der Serverinstanz gemeinsam genutzt, so dass es auf diese Weise einfach sein könnte, sie mit Hilfe einer Map abzugleichen.
Die direkte Verwendung einer Karte in einem ähnlichen Anwendungsfall war jedoch nach wie vor unelegant. Jemand könnte argumentieren, dass die Verwendung einer Map komplizierter zu verwalten und zu handhaben ist.
Aus diesen Gründen habe ich eine Bibliothek namens MagicSet implementiert, die die Verwendung einer Map für den Entwickler "transparent" macht.
https://github.com/ricpacca/magicset
Wie das ursprüngliche Java HashSet verwendet ein MagicHashSet (eine der Implementierungen von MagicSet, die in der Bibliothek enthalten sind) eine unterstützende HashMap, aber anstatt Elemente als Schlüssel und einen Dummy-Wert als Wert zu haben, verwendet es die UUID des Elements als Schlüssel und das Element selbst als Wert. Dies verursacht keinen Overhead bei der Speichernutzung im Vergleich zu einem normalen HashSet.
Außerdem kann ein MagicSet genau wie ein Set verwendet werden, jedoch mit einigen weiteren Methoden, die zusätzliche Funktionen bieten, wie getFromId(), popFromId(), removeFromId() usw.
Die einzige Voraussetzung für die Verwendung ist, dass jedes Element, das Sie in einem MagicSet speichern möchten, die abstrakte Klasse UniqueItem erweitern muss.
Hier ein Code-Beispiel, in dem die ursprüngliche Instanz einer Stadt aus einem MagicSet abgerufen werden soll, wenn eine andere Instanz dieser Stadt mit derselben UUID (oder auch nur ihrer UUID) vorliegt.
class City extends UniqueItem {
// Somewhere in this class
public void doSomething() {
// Whatever
}
}
public class GameMap {
private MagicSet<City> cities;
public GameMap(Collection<City> cities) {
cities = new MagicHashSet<>(cities);
}
/*
* cityId is the UUID of the city you want to retrieve.
* If you have a copied instance of that city, you can simply
* call copiedCity.getId() and pass the return value to this method.
*/
public void doSomethingInCity(UUID cityId) {
City city = cities.getFromId(cityId);
city.doSomething();
}
// Other methods can be called on a MagicSet too
}