Ответ 1
Метод Arrays.asList(...)
предоставляет представление списка базового массива.
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
имеет очень мало общего с неизменностью. Возвращенный список не может добавлять или удалять элементы, но его можно изменить, а изменения изменят базовый массив. Фактически класс возвращаемого списка является специальным, который использует массив для хранения. Это похоже на это:
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.
Это безопасно, только если вы выбрали исходный список, как в этом примере карты. Поскольку map
выходит за рамки, ничто не может изменить базовую карту немодифицируемого отображения 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 ImmutableList
создает новую копию данных, если исходные данные не сохраняются неизменно сами. Цитирование docs:
Полезно помнить, что ImmutableXXX.copyOf пытается избежать копирования данных, когда это безопасно, - точные данные не указаны, но реализация, как правило, "умна".
Таким образом, у Guava есть свои неизменные коллекции, независимые от их происхождения.
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 data.