Czy istnieją zalety między tworzeniem listy w jednym wierszu a com.google.common.collect.ImmutableList.of(...)
i java.util.Arrays.asList(...)
?Tablice JDK vs. ImmutableList Guawy
Odpowiedz
Metoda Arrays.asList(...)
zapewnia listę , widok z podstawowej tablicy.
Integer[] numbers = {17, 42, 2001};
List<Integer> list = Arrays.asList(numbers);
System.out.println(list.get(0)); // Prints 17.
list.remove(0); // throws.
numbers[0] = 1;
System.out.println(list.get(0)); // Prints 1.
list.set(0, 17);
System.out.println(numbers[0]); // Prints 17.
Arrays.asList
ma bardzo niewiele wspólnego z niezmiennością. Zwrócona lista nie może zawierać elementów dodanych ani usuniętych, ale można ją zmienić, a zmiany zmieniają bazową tablicę. W rzeczywistości klasa zwróconej listy jest specjalną, która używa tablicy do przechowywania. Jest to podobne do tego:
List<Integer> integers = new ArrayList<>();
integers.add(17);
integers.add(42);
integers.add(2001);
List<Integer> unmodifiable = Collections.unmodifiableList(integers);
unmodifiable.set(0, 1); // throws.
unmodifiable.remove(0); // throws.
unmodifiable.add(867_5309); // throws.
integers.set(0, 1) // okay.
System.out.println(unmodifiable.get(0)); // Prints 1.
Jest to bezpieczne tylko wtedy, gdy wyrzuci się oryginalną listę, tak jak w tym przykładzie mapy. Ponieważ map
wychodzi poza zakres, nic nie może zmienić podstawowej mapy niezmodyfikowanej mapy CAPITALS
.
public static final Map<String, String> CAPITALS;
static {
Map<String, String> map = new HashMap<>();
map.put("USA", "Washington, DC");
map.put("England", "London");
// ...
CAPITALS = Collections.unmodifiableMap(map);
}
Guava na ImmutableList
tworzy nową kopię danych, czy oryginalne dane nie są przechowywane niezmiennie sama. Cytując jego docs:
Warto pamiętać, że ImmutableXXX.copyOf próbuje uniknąć kopiowania danych, gdy jest to bezpieczne - dokładne dane są nieokreślone, ale realizacja jest zwykle „inteligentne”.
Tak, Guava ma swoje niezmienne kolekcje niezależnie od ich pochodzenia.
List<Integer> original = new ArrayList<>();
original.add(1);
original.add(2);
original.add(3);
ImmutableList<Integer> immutable = ImmutableList.copyOf(original);
immutable.set(0, 42); // throws.
System.out.println(immutable.get(0)); // Prints 1.
original.set(0, 42); // fine.
System.out.println(immutable.get(0)); // Prints 1.
ImmutableList<Integer> copy = ImmutableList.copyOf(immutable);
// Shares immutable's data.
+1 zwięzłe wyjaśnienie – ajduke