2012-02-01 16 views
13

Obecnie używamy Guava do jej niezmiennych zbiorów, ale byłem zaskoczony, że ich mapy nie mają metod łatwego tworzenia nowych map z niewielkimi modyfikacjami. Ponadto, ich konstruktor nie pozwala na przypisywanie nowych wartości do kluczy ani usuwanie kluczy.Efektywnie "modyfikując" niezmienną mapę

Więc gdybym chciał modyfikować tylko jedną wartość, oto co chciałbym być w stanie to zrobić:

ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */; 
ImmutableMap<Guid, ImmutableMap<String, Integer>> modifiedMap = 
    originalMap.cloneAndPut(key, value); 

Oto jak to wygląda Guava oczekują mi zrobić:

ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */; 
Map<Guid, ImmutableMap<String, Integer>> mutableCopy = new LinkedHashMap<>(originalMap); 
mutableCopy.put(key, value); 
originalMap = ImmutableMap.copyOf(mutableCopy); 
/* put the map back */ 

Robiąc to otrzymuję nową kopię mapy z modyfikacją, której chcę. Oryginalna kopia jest nietknięta i będę używał atomowego odniesienia, aby przywrócić rzecz, aby cała konfiguracja była bezpieczna dla wątków.

Jest po prostu powolny.

Tutaj jest dużo zmarnowanego kopiowania. Załóżmy, że na mapie jest 1024 wiadra. To jest 1023 wiadra, które niepotrzebnie tworzysz od nowa (dwa razy za każdym razem), kiedy mogłeś wykorzystać niezmienne wiadra tak jak jest i sklonował tylko jeden z nich.

Więc myślę:

  1. Czy istnieje metoda narzędzie Guava pochowany gdzieś na tego typu rzeczy? (Nie ma go w Mapach ani na ImmutableMap.Builder.)

  2. Czy jest jakaś inna biblioteka Java, która ma takie rzeczy w porządku? Jestem pod wrażeniem, że Clojure ma tego rodzaju rzeczy pod maską, ale nie jesteśmy gotowi do przełączania języków jeszcze ...

+0

Prosimy o przesłanie żądania funkcji, jeśli chcesz, ale prawdopodobnie szukasz biblioteki odpowiednich struktur danych funkcjonalnych. –

+0

Tak. To jest coś, co można zrobić - to właśnie robią języki funkcjonalne - ale to nie jest guava. Guawa na przykład 'ImmutableMap' jest oparta na haszowaniu, a to nie zapewni wydajnej aktualizacji, nie bez znacznej ceny w szybkości zapytań. –

+0

Rephrase: niezmienne kolekcje Guava są budowane dla szybkiego zapytania/iteracji i minimalnego zużycia pamięci. Oznacza to mieszanie i tablice, które nie pozwolą ci obsługiwać skutecznych nieniszczących aktualizacji. –

Odpowiedz

6

Trochę nieoczekiwanych map of Functional Java jest zmienny jak Guava jest. Lista jest niezmienna, jak można by się spodziewać.

Googling dla "trwałej kolekcji java" wychowanej: pcollections. Jest tam Map implementation.

Zanim zacznę używać jakiejkolwiek innej implementacji, porównuję pamięć i charakterystykę wydajności z Guava. Nie zdziwiłbym się, gdyby było jeszcze lepiej.

Powiązane problemy