Możesz użyć MutableMapIterable.updateValueWith(K key, Function0<? extends V> factory, Function2<? super V,? super P,? extends V> function, P parameter)
z Eclipse Collections.
Argument factory
tworzy wartość początkową, jeśli żadna nie jest na mapie. Argument function
jest stosowany do wartości mapy wraz z dodatkowym parametrem, aby wymyślić nową wartość mapy. Ten parameter
jest przekazywany jako ostatni argument do updateValueWith()
. Funkcja jest wywoływana nawet w przypadku, gdy klucza nie ma na mapie. Tak więc początkowa wartość to naprawdę function
zastosowana do wyjścia factory
i parameter
. The function
nie może mutować wartości; powinien zwrócić nową wartość. W twoim przykładzie wartościami mapy są ciągi, które są niezmienne, więc nic nam nie jest.
W ConcurrentMaps takich jak org.eclipse.collections.impl.map.mutable.ConcurrentHashMap
, implementacja updateValueWith()
jest również wątkowa i atomowa. Ważne jest, aby function
nie zmutował wartości mapy lub nie byłby bezpieczny dla wątków. Zamiast tego powinien zwrócić nowe wartości. W twoim przykładzie wartościami mapy są ciągi, które są niezmienne, więc nic nam nie jest.
Jeśli twoja metoda recalculateNewValue()
po prostu wykonuje konkatenację ciągów, oto jak możesz użyć updateValueWith()
.
Function0<String> factory =() -> "initial ";
Function2<String, String, String> recalculateNewValue = String::concat;
MutableMap<String, String> map = new ConcurrentHashMap<>();
map.updateValueWith("test", factory, recalculateNewValue, "append1 ");
Assert.assertEquals("initial append1 ", map.get("test"));
map.updateValueWith("test", factory, recalculateNewValue, "append2");
Assert.assertEquals("initial append1 append2", map.get("test"));
Można użyć Java 8 na ConcurrentMap.compute(K key, BiFunction remappingFunction) aby osiągnąć to samo, ale ma kilka wad.
ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
map.compute("test", (key, oldValue) -> oldValue == null ? "initial append1 " : oldValue + "append1 ");
Assert.assertEquals("initial append1 ", map.get("test"));
map.compute("test", (key, oldValue) -> oldValue == null ? "initial append1 " : oldValue + "append2");
Assert.assertEquals("initial append1 append2", map.get("test"));
- Nie ma oddzielne fabryki obsłużyć przypadku kluczy nieobecnych więc ciało lambda ma do czynienia z wartościami i wartości początkowych.
- Interfejs API nie umożliwia ponownego używania lambd. Każde połączenie z
updateValueWith()
ma te same lambdy, ale każde połączenie z compute()
tworzy nowe śmieci na stercie.
Uwaga: Jestem committer dla Eclipse Kolekcje
Rozumiem, dziękuję. To trochę bardziej kompaktowe. – Holger
Co powiesz na pominięcie 'String's i umieszczenie wszystkiego bezpośrednio w' if'? – elect
Jeśli inny wątek zmieni wartość między putIfAbsent i zastąpi cię niespójną wartością. – Uberto