Jakie są sytuacje, w których mogę skorzystać Collections.emptyMap()
? Dokumentacja mówi, że mogę użyć tej metody, jeśli chcę, aby moja kolekcja była niezmienna.
Dlaczego miałbym chcieć niezmiennej, pustej kolekcji? O co chodzi?
java
collections
Vinoth Kumar CM
źródło
źródło
[NSArray array]
, zwraca obiekt, który chociaż nie nadaje się do użytku, ale istnieje. Możesz więc bawić się nim jak normalnym przedmiotem i nie otrzymać błędu.Odpowiedzi:
Od Effective Java , poz # 43 -
"Return empty arrays or collections, not null"
demonstruje powrocie pustą kolekcję, a może nawet demonstruje przy użyciu tychemptyList()
,emptySet()
orazemptyMap()
metody na zbiorach klasy, aby uzyskać pustą kolekcję, która ma również dodatkową zaletę, że są niezmienne. Z przedmiotu nr 15"Minimize Mutability"
.Z kolekcji-emptySet-Collections-emptyList-Collections
Uwaga: poniższy kod to tylko przykład (zmień go w zależności od przypadku użycia):
Te metody mają kilka zalet:
Są bardziej zwięzłe, ponieważ nie trzeba jawnie wpisywać typu ogólnego kolekcji - zwykle jest on po prostu wywnioskowany z kontekstu wywołania metody.
Są bardziej wydajne, ponieważ nie zawracają sobie głowy tworzeniem nowych obiektów; po prostu ponownie wykorzystują istniejący pusty i niezmienny obiekt. Ten efekt jest ogólnie bardzo niewielki, ale czasami (no cóż, rzadko) ważny.
źródło
Set
iHashSet
w twoich przykładach, ponieważ celememptySet()
metody i przyjaciół (w przeciwieństwie do stałychCollections.EMPTY_SET
itp.) Jest to, że dobrze się bawią z rodzajami. Ponadto używanie funkcji (typów surowych), która jest przestarzała od czasu Java 5, nie jest dobrą pomocą dydaktyczną.Collection
zamiast tego,null
aby uniknąćExceptions
rzucenia się na kolejne operacje? Użycie niezmiennej kolekcji spowodowałoby po prostu inny rodzaj wyjątku, jaki sobie wyobrażam. A przypisanie znull
pewnością nie jest mniej wydajne niż przypisanie niezmiennej stałej.public boolean setExists() { return !myset.equals(Collections.emptySet()); }
Z mojego osobistego doświadczenia wynika, że jest to bardzo przydatne w przypadkach, gdy API wymaga zbioru parametrów, ale nie masz nic do dostarczenia. Na przykład możesz mieć interfejs API, który wygląda mniej więcej tak i nie zezwala na zerowe odwołania:
Jeśli masz zapytanie, które nie przyjmuje żadnych parametrów, z pewnością trochę marnotrawstwem jest tworzenie HashMap, które obejmuje alokację tablicy, podczas gdy możesz po prostu przekazać `` Pustą mapę '', która jest faktycznie stałą, sposób jej implementacji w
java.util.Collections
.źródło
Istnieją tutaj dwie różne koncepcje, które wydają się dziwne, gdy ogląda się je razem. Ma to większy sens, gdy traktujesz te dwie koncepcje oddzielnie.
Po pierwsze, jeśli to tylko możliwe, wolisz używać niezmiennej kolekcji, a nie mutowalnej. Korzyści z odporności są dobrze udokumentowane gdzie indziej .
Po drugie, wolisz używać pustej kolekcji niż używać null jako wartownika. Jest to dobrze opisane tutaj . Oznacza to, że będziesz mieć znacznie bardziej przejrzysty i łatwiejszy do zrozumienia kod, z mniejszą liczbą miejsc do ukrycia błędów.
Więc jeśli masz kod, który wymaga mapy, lepiej jest przekazać pustą mapę niż wartość null, aby wskazać brak mapy. W większości przypadków, gdy używasz mapy, lepiej jest użyć niezmiennej mapy. Dlatego właśnie istnieje wygodna funkcja tworzenia niezmiennej pustej mapy.
źródło
Jest kilka przypadków, w których wolisz używać niezmiennych map, list, zestawów lub innych typów kolekcji.
Pierwszym i prawdopodobnie najważniejszym przypadkiem użycia jest to, że zawsze, gdy zwracasz wynik zapytania lub obliczenia, które zwróciłyby zestaw (lub listę lub mapę) wyników, powinieneś preferować użycie niezmiennych struktur danych.
W tym przypadku wolę zwracać ich niezmienne wersje, ponieważ odzwierciedla to faktyczną niezmienność zestawu wyników obliczeń znacznie wyraźniej - bez względu na to, co zrobisz z danymi później, zestaw wyników otrzymanych z zapytania nie powinien zmiana.
Drugim typowym przypadkiem użycia jest podanie argumentu jako danych wejściowych do metody lub usługi. O ile nie spodziewasz się, że kolekcja wejściowa zostanie zmodyfikowana przez usługę lub metodę (co zwykle jest naprawdę złym pomysłem projektowym), przekazanie niezmiennej kolekcji zamiast mutowalnej może być w wielu przypadkach rozsądnym i bezpiecznym wyborem.
Myślę o tym jako o konwencji „przekazywania wartości” .
Mówiąc bardziej ogólnie - rozsądną praktyką jest stosowanie niezmiennych struktur danych, gdy dane przekraczają granice modułów lub usług. To znacznie ułatwia wnioskowanie o różnicach między (niezmiennym) wejściem / wyjściem a zmiennym stanem wewnętrznym.
Bardzo korzystnym efektem ubocznym jest zwiększone bezpieczeństwo i bezpieczeństwo wątków Twoich modułów / usług oraz zapewnia czystsze oddzielenie problemów.
Innym dobrym powodem do używania
Collections.empty*()
metod jest ich zauważalny brak słownictwa. W erze przed Java7, jeśli miałeś kolekcję ogólną, musiałeś posypać adnotacjami typu ogólnego w każdym miejscu.Wystarczy porównać te dwie deklaracje:
przeciw:
Ta ostatnia wyraźnie wygrywa pod względem czytelności na dwa ważne sposoby:
fooBarMap
jest przypisywana kolejna niepusta wartość, po prostu wyszukując/fooBarMap =/
.źródło
Po pierwsze, możesz uciec dzięki udostępnianiu referencji. A
new HashMap()
etc będzie wymagało przydzielonego obiektu i prawdopodobnie kilku dodatkowych elementów do przechowywania danych, ale potrzebujesz tylko jednej kopii niezmiennej pustej kolekcji (lista, zestaw, mapa lub dowolna inna). To sprawia, że jest to oczywisty wybór, gdy wywoływana metoda musi akceptować Mapę, ale nie musi jej edytować.Proponuję sprawdzić efektywną Javę Josha Blocha , która wymienia kilka bardzo ładnych atrybutów niezmiennych obiektów (w tym bezpieczeństwo wątków).
źródło
Może to być przydatne, gdy masz funkcję, która zwraca
immutable collection
a, aw niektórych sytuacjach nie ma danych do zwrócenia, więc zamiast zwracaćnull
możesz zwrócićemptyMap()
Ułatwia kod i zapobiega
NullPointerException
źródło
Przez większość czasu używamy a
constructor
do tworzenia nowegoempty map
. AleCollections
methods
oferuje kilka zalet, aby stworzyćempty map
usingstatic
method
java.util.Collections.emptyMap()
źródło
Z tego samego powodu, którego używałbyś
Collections.unmodifiableMap()
w pewnym momencie. Chcesz zwrócić wystąpienie Map, które zgłasza wyjątek, jeśli użytkownik spróbuje go zmodyfikować. To tylko szczególny przypadek: pusta mapa.źródło
Z tych samych powodów, dla których możesz chcieć niezmiennych obiektów. Przede wszystkim dlatego, że możesz spać bezpiecznie w nocy, wiedząc, że wiele wątków może uzyskać dostęp do tego samego wystąpienia obiektu i że wszystkie będą widzieć te same wartości. Brak elementów w kolekcji jest nadal prawidłową wartością, którą chciałbyś zachować.
źródło