2017-09-25 60 views
13

Czy istnieje różnica między Map.of() i Collections.emptyMap() między List.of() i Collections.emptyList() oraz między Set.of() i Collections.emptySet()?Map.of()() vs. Collections.emptyMap

+1

Jaką różnicę szukasz? Nazwy metod różnią się, ale wynikowe struktury danych zachowują się bardzo podobnie. –

+0

@ C-Otto Jeśli twierdzisz, że metody są po prostu "bardzo podobne" (i nie identyczne), musisz oczywiście myśleć, że istnieje różnica. – jarnbjo

+0

@jarnbjo są różnice - zobacz moją odpowiedź – xenteros

Odpowiedz

17

Tak, istnieją nawet behawioralne, a nie różnice tylko technicznych między zbiorami zwracanych przez metody fabrycznych emptyXyz w klasie Collections i nowych of metod fabrycznych wprowadzonych w interfejsy (Map, List, Set) z JDK 9 , jeśli są wywoływane bez żadnych argumentów.

Odpowiednia różnica jest taka, że ​​zbiory zwracane przez nowe of metod fabrycznych zabronić null klucze i wartości (jak wskazano w dokumentacji API w List, Set i Map interfejsów). Może to brzmieć nieistotnie dla pustych kolekcji, ale nawet jeśli nie jest to do końca udokumentowane, nawet metody dostępu w nowych implementacjach kolekcji sprawdzają wartości puste.

Niektóre przykłady różnic:

Collections.emptyList().contains(null) zwróci false, a List.of().contains(null) rzuci NullPointerException.

zwróci V, natomiast Map.of().getOrDefault(null, V) wyrzuci NullPointerException.

Zgodnie z aktualnie wdrożonym w Oracle JDK 9, co najmniej następujące metody na kolekcje zwrócone przez nowe metody fabryczne rzucają NullPointerException s, ale zachowują się "sanely" (jak w tym, w jaki sposób klasy kolekcji zostały pierwotnie zaprojektowane i określone do obsługi klucze i wartości zerowe) przy użyciu starych metod fabrycznych w klasie Collections:

  • List.of().contains(null);
  • Set.of().contains(null);
  • Map.of().containsKey(null);
  • Map.of().containsValue(null);
  • Map.of().getOrDefault(null, <any>);
+0

+1 To dobrze. Być może, gdy zwrócisz uwagę na "jak wskazano w dokumentacji API", określ sekcję we wszystkich typach kolekcji: * "Immutable Statyczne metody fabryczne" *, gdzie wyjaśniono właściwości tych wystąpień. – slim

+0

Również "sanely" jest dyskusyjny - NPE jest prawdopodobnie bardziej rozsądny, ale nie zgodny wstecz. – slim

+5

@slim tutaj nie ma problemu z kompatybilnością wsteczną tutaj. Metody 'X.of()' są nowe i nie mają na celu bezpośredniej zamiany metod 'Collections.emptyX()'. Istniejący kod będzie działał jak w starszych wersjach Javy. – Jesper