Es gibt keine genaue Entsprechung, aber die übliche Vorgehensweise ist so etwas wie diese:
ConcurrentMap<Key,Value> map = ...
Value computeIfAbsent(Key k) {
Value v = map.get(k);
if (v == null) {
Value vNew = new Value(...); // or whatever else you do to compute the value
v = (v = map.putIfAbsent(k, vNew)) == null ? vNew : v;
}
return v;
}
Das ist so ziemlich funktional äquivalent der computeIfAbsent
Anruf in Java 8, mit dem einzigen Unterschied, dass manchmal konstruieren Sie ein Value
Objekt, das es niemals in die Map schafft - weil ein anderer Thread es zuerst eingefügt hat. Es führt nie dazu, das falsche Objekt oder etwas Ähnliches zurückzugeben - die Funktion liefert immer das richtige Value
egal was, aber , wenn die Konstruktion von Value Nebenwirkungen hat *, kann dies nicht akzeptabel sein.
Die zusätzlichen Instanzen sind im Allgemeinen kein Leistungsproblem, da die erste Überprüfung get()
die meisten Aufrufe an putIfAbsent
entfernt. Im Allgemeinen kann dieser Ansatz erheblich schneller als computeIfAbsent
sein, weil dieser Aufruf unnötiges Sperren von Objekten durchführt, wenn das Objekt bereits vorhanden ist. Lokal habe ich es als 5 mal schneller gemessen, wenn da einige Objekte stark umkämpft sind.
Wenn Sie wirklich das Rechenverhalten müssen in die Karte integriert (mit einer internen Sperre gehalten so genau einem Thread das neue Objekt erzeugt), können Sie Guava die Verwendung CacheBuilder
ein LoadingCache
zu bekommen. Es ist im Wesentlichen das gleiche Verhalten wie Java 8 CHM, aber mit einer Tonne zusätzlicher Konfigurationsoptionen.
Gibt es etwas über 'if (! Map.containsKey (key))', das nicht für Sie funktioniert? – Zircon
@Zircon computeIfAbsent fügt das Ergebnis der Funktion atomisch als neuen Wert für diesen Schlüssel ein. Das ist also kein 100% Ersatz ohne zusätzliche Arbeit. –
@SotiriosDelimanolis Er sagt ausdrücklich, er will, dass es atomar ist. Also nein, es gibt kein Äquivalent. Sie können ein Äquivalent schreiben, aber Sie müssen Ihre eigenen Sperren mit einem expliziten Semaphor durchführen. –