Относительно неизменного списка (созданного Arrays.asList())
Когда мы создаем список из массива, используя java.util.Arrays.asList()
, список неизменен. Мне просто любопытно узнать, почему мы хотим создать неизменный список, когда основная цель List
(или же Set
или же Map
) должен иметь динамический размер и иметь возможность добавлять, удалять элементы по желанию. Когда нам нужна структура данных фиксированного размера, мы выбираем массив, а когда нам нужна динамическая структура данных, мы выбираем List
или же Set
или же Map
и т.д. Так, какова цель иметь неизменный список? Я сталкивался с этим, работая над своим заданием.
4 ответа
Когда мы создаем список из массива с помощью java.util.Arrays.asList(), список является изменяемым.
Да и нет: список можно изменить, позвонив
list.set(index, element);
Но список не может быть структурно изменен. Это означает, что невозможно добавить элементы в список или удалить элементы из списка. Причина просто в том, что список все еще поддерживается массивом, и размер массива может не измениться.
Когда нам нужна изменяемая коллекция фиксированного размера, мы выбираем массив
И это ключевой момент здесь: массив не является коллекцией. Arrays.asList
Метод в основном служит "мостом" между "миром массивов" и "миром коллекций".
Arrays.asList
Метод позволяет, например, передать данные в метод, который ожидает Collection
:
// A method that expects a collection:
void process(List<String> strings) { ... }
void call()
{
String array[] = new String[] { "A", "B", "C" };
// Pass the array (as a list) to the method:
process(Arrays.asList(array));
}
Этот случай применения включает в себя создание других коллекций из массива. Например, если у вас есть массив и вы хотите создать Set
содержащий элементы из массива, вы можете
String array[] = new String[] { "A", "B", "C" };
Set<String> set = new HashSet<String>();
for (String s : array)
{
set.add(s);
}
Но с Arrays.asList
Метод, это можно сделать удобнее:
Set<String> set = new HashSet<String>(Arrays.asList(array));
Arrays.asList
метод, так сказать, аналог метода Collection # toArray, который работает в противоположном направлении (хотя этот метод обычно включает создание и заполнение нового массива, тогда как Arrays.asList
Метод просто "оборачивает" массив и позволяет ему "выглядеть" List
).
java.util.Arrays.asList()
звонки return new ArrayList<>(a);
но этот ArrayList является частным классом массивов, который расширяет AbstractList
и переопределить некоторые реализации. Так что нечестно ожидать, что поведение java.util.ArrayList
, Если вы посмотрите в java.util.AbstractList
вы увидите, что вы можете вызвать add(E e), но не так много других методов. Итак, согласно текущей реализации, вы можете добавить элемент внизу списка, но не можете изменить существующую структуру списка.
Если вы позвоните
System.out.println(Arrays.asList("a", "b").getClass());
тип среды выполнения
java.util.Arrays$ArrayList
,
но если вы позвоните
System.out.println(new ArrayList<>(Arrays.asList("a", "b").getClass()));
тип среды выполнения
java.util.ArrayList
.
Может быть, это различие помогает.
Это из-за add()
в классе AbstractList, расширенный настраиваемым ArrayList (внутренним статическим классом) в Java-классе Arrays (который используется внутри). Обратите внимание, что этот метод add() отличается от метода, определенного в java.util.ArrayList, но он java.util.Arrays$ArrayList
,
Массив обладает свойством фиксированного размера, предоставленного изначально jvm. Даже если Arrays.copyOf() используется с увеличенным размером, таким как Arrays.copyOf(arr, 10); //10 is the length
где оригинальный массив arr= int[]{1,2} // size is two
, Он всегда создает новый массив, используя System.arraycopy()
который в конечном итоге вызывает нативный метод.
[static void arraycopy (Object src, int srcPos, Object dest, int destPos, int length)]
Обратите внимание, что приведенный выше список имеет только ограничения по размеру. Если вы действительно хотите сделать изменяемый список неизменным, попробуйте использовать Collections.unmodifiableList(mutableList);
Неизменность - это не концепция, определенная jvm, а мысль разработчика. пожалуйста, обратитесь /questions/29451186/chto-takoe-permskoe-prostranstvo/29451212#29451212 и /questions/22715803/pochemu-klass-string-obyavlen-finalnyim-v-java/22715816#22715816