W praktyce, czy lepiej jest zwrócić pustą listę w następujący sposób :
return Collections.emptyList();
Albo jak to :
return new ArrayList<Foo>();
Czy może to całkowicie zależy od tego, co zrobisz ze zwróconą listą?
W praktyce, czy lepiej jest zwrócić pustą listę w następujący sposób :
return Collections.emptyList();
Albo jak to :
return new ArrayList<Foo>();
Czy może to całkowicie zależy od tego, co zrobisz ze zwróconą listą?
Odpowiedzi:
Główną różnicą jest to, że Collections.emptyList()
zwraca niezmienną listę, tj. Listę, do której nie można dodawać elementów. (To samo dotyczy List.of()
wprowadzonych w Javie 9.)
W rzadkich przypadkach, gdy chcesz zmodyfikować zwróconą listę, Collections.emptyList()
a List.of()
zatem nie są dobrym wyborem.
Powiedziałbym, że zwrócenie niezmiennej listy jest całkowicie w porządku (a nawet preferowanym sposobem), o ile umowa (dokumentacja) wyraźnie nie określa inaczej.
Ponadto emptyList()
może nie utworzyć nowego obiektu przy każdym wywołaniu.
Implementacje tej metody nie muszą tworzyć osobnego obiektu List dla każdego wywołania. Korzystanie z tej metody prawdopodobnie będzie miało koszt porównywalny z użyciem pola o podobnej nazwie. (W przeciwieństwie do tej metody pole nie zapewnia bezpieczeństwa typu).
Implementacja emptyList
wygląda następująco:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
Jeśli więc twoja metoda (która zwraca pustą listę) jest wywoływana bardzo często, to podejście może nawet dać ci nieco lepszą wydajność zarówno pod względem procesora, jak i pamięci.
NullPointerException
zwrotu, Collections.emptyList()
zamiast null
.
Collections.emptyList()
jest iterowalny i zwraca długość, dzięki czemu można go używać w pętlach bez zgłaszania wyjątku.
new ArrayList<>()
wyraźnie wyjaśnia decyzję projektową; elementy nie zostaną dodane do tej listy.
Począwszy od Java 5.0 możesz określić typ elementu w kontenerze:
Collections.<Foo>emptyList()
Zgadzam się z innymi odpowiedziami, że w przypadkach, w których chcesz zwrócić pustą listę, która pozostaje pusta, powinieneś zastosować to podejście.
List<Foo> list = Collections.emptyList()
Collections.emptyList
jest niezmienny, więc istnieje różnica między dwiema wersjami, więc musisz wziąć pod uwagę użytkowników zwracanej wartości.
Zwracanie new ArrayList<Foo>
zawsze tworzy nową instancję obiektu, więc wiąże się z nią bardzo niewielki dodatkowy koszt, który może być powodem do użycia Collections.emptyList
. Lubię używać emptyList
tylko dlatego, że jest bardziej czytelny.
Bądź jednak ostrożny. Jeśli wrócisz, Collections.emptyList()
a następnie spróbujesz wprowadzić pewne zmiany, takie jak add()
lub coś w tym stylu, będziesz mieć UnsupportedOperationException()
bo, ponieważ Collections.emptyList()
zwraca niezmienny obiekt.
Poszedłbym z Collections.emptyList()
jeśli zwrócona lista nie jest w żaden sposób modyfikowana (ponieważ lista jest niezmienna), w przeciwnym razie wybrałbym opcję 2.
Zaletą Collections.emptyList()
jest to, że za każdym razem zwracana jest ta sama instancja statyczna, dlatego nie ma tworzenia instancji dla każdego wywołania.
Użyj Collections.emptyList (), jeśli chcesz mieć pewność, że zwrócona lista nigdy nie zostanie zmodyfikowana. Oto, co jest zwracane po wywołaniu emptyList ():
/**
* The empty list (immutable).
*/
public static final List EMPTY_LIST = new EmptyList();
Collections.emptyList()
ma koszt budowy. Wyświetlanie szczegółów implementacji (choć prawdopodobnie nie jest takie samo na wszystkich maszynach JVM) potwierdza, że tak nie jest. @Atul, z której to JVM?
Podane odpowiedzi podkreślają fakt, że emptyList()
zwraca niezmienne, List
ale nie dają alternatyw. ArrayList(int initialCapacity)
Przypadki specjalne Konstruktora, 0
więc powrót new ArrayList<>(0)
zamiast new ArrayList<>()
może być również realnym rozwiązaniem:
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
[...]
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
(źródła z Java 1.8.0_72)
Collections.emptyList()
bardziej odpowiednie, powiedzmy, sprawdzanie błędów i tym podobne?