Когда мы создаем список из массива с помощью java.util.Arrays.asList()
, список является неизменным. Мне просто интересно узнать, почему мы хотим создать неизменяемый список, если основная цель List
(или Set
или Map
) состоит в том, чтобы иметь динамический размер и возможность добавлять, удалять элементы по своему усмотрению. Когда нам нужна структура данных фиксированного размера, мы идем для Array, и когда нам нужна динамическая структура данных, мы идем на List
или Set
или Map
и т.д. Итак, в чем цель создания неизменяемого списка? Я столкнулся с этим, работая над своим заданием.
Ответ 1
Когда мы создаем список из массива с помощью java.util.Arrays.asList(), список изменен.
Да и нет: список может быть изменен, вызывая
list.set(index, element);
Но список может не быть структурно изменен. Это означает, что невозможно добавить элементы в список или удалить элементы из списка. Причина в том, что список по-прежнему поддерживается массивом, и размер массива может не измениться.
Когда нам нужна коллекция с изменяемым размером, мы переходим к массиву
И вот здесь ключевой момент: массив не a Collection. Метод 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
).
Ответ 2
Это связано с add()
в классе AbstractList, расширенным настраиваемым ArrayList (внутренним статическим классом) под классом класса 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);
Immutablility - это не определенная jvm концепция, а идея разработчика. пожалуйста, обратитесь fooobar.com/questions/23617/... и fooobar.com/questions/6447/...
Ответ 3
java.util.Arrays.asList()
вызывает return new ArrayList<>(a);
но этот ArrayList является частным классом массивов, который расширяет AbstractList
и отменяет некоторую реализацию. Таким образом, несправедливо ожидать поведения java.util.ArrayList
. Если вы посмотрите в java.util.AbstractList
вы увидите, что вы можете вызвать add (E e), но не так много других методов. Таким образом, в соответствии с текущей реализацией вы можете добавить элемент в нижней части списка, но не можете изменить существующую структуру списка.