Zespół Java wykonał mnóstwo świetnej pracy, usuwając bariery w programowaniu funkcjonalnym w Javie 8. W szczególności zmiany w kolekcjach java.util wykonują świetną robotę, łącząc przekształcenia w bardzo szybko przesyłane strumieniowo operacje. Biorąc pod uwagę, jak dobrą robotę wykonali, dodając pierwszorzędne funkcje i metody funkcjonalne do kolekcji, dlaczego całkowicie nie udało się zapewnić niezmiennych kolekcji, a nawet niezmiennych interfejsów kolekcjonowania?
Bez zmiany żadnego istniejącego kodu zespół Java może w dowolnym momencie dodać niezmienne interfejsy, które są takie same jak zmienne, pomniejszone o metody „set” i sprawić, by istniejące interfejsy rozszerzyły się z nich, w następujący sposób:
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
Jasne, operacje takie jak List.add () i Map.put () obecnie zwracają wartość logiczną lub poprzednią wartość dla danego klucza, aby wskazać, czy operacja się powiodła, czy nie. Niezmienne kolekcje musiałyby traktować takie metody jak fabryki i zwracać nową kolekcję zawierającą dodany element - co jest niezgodne z obecną sygnaturą. Ale można to obejść, używając innej nazwy metody, takiej jak ImmutableList.append () lub .addAt () i ImmutableMap.putEntry (). Wynikająca z tego gadatliwość byłaby bardziej niż przeważona korzyściami pracy z niezmiennymi kolekcjami, a system typów zapobiegałby błędom wywołania niewłaściwej metody. Z czasem stare metody mogły być przestarzałe.
Zwycięstwa niezmiennych kolekcji:
- Prostota - rozumowanie na temat kodu jest prostsze, gdy podstawowe dane nie ulegają zmianie.
- Dokumentacja - jeśli metoda przyjmuje niezmienny interfejs kolekcji, wiesz, że nie będzie modyfikować tej kolekcji. Jeśli metoda zwraca niezmienną kolekcję, wiesz, że nie możesz jej zmodyfikować.
- Współbieżność - niezmienne kolekcje można bezpiecznie współdzielić między wątkami.
Jako osoba, która próbowała języków, które zakładają niezmienność, bardzo trudno jest wrócić na Dziki Zachód szalonej mutacji. Kolekcje Clojure (abstrakcja sekwencji) mają już wszystko, co zapewniają kolekcje Java 8, oraz niezmienność (choć może zużywa dodatkową pamięć i czas z powodu zsynchronizowanych list połączonych zamiast strumieni). Scala ma zarówno kolekcje zmienne, jak i niezmienne z pełnym zestawem operacji i chociaż operacje te są chętne, wywołanie .iterator daje leniwy widok (i istnieją inne sposoby leniwej ich oceny). Nie rozumiem, jak Java może nadal konkurować bez niezmiennych kolekcji.
Czy ktoś może wskazać mi historię lub dyskusję na ten temat? Z pewnością jest to gdzieś publiczne.
const
kolekcje
Collections.unmodifiable*()
. ale nie traktuj ich jako niezmiennych, gdy nie są
ImmutableList
ten schemat, ludzie mogą przejść mutable List
? Nie, to bardzo złe naruszenie LSP.