#java #arrays #list #arraylist
#java #массивы #Список #arraylist
Вопрос:
Я проходил через реализацию Arrays.asList()
.Если мы попытаемся изменить размер массива с помощью List(I)
определенных методов, то получим RE: UnsupportedException
. Реализация —
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
Согласно приведенной выше реализации, поскольку ArrayList
объект возвращается asList
, почему мы не можем изменить размер возвращаемого List
объекта?
В частности, что мешает изменить размер возвращаемого ArrayList
объекта?
Любые предложения были бы полезны и оценены.
Комментарии:
1. Вы уверены, что используется именно такая перегрузка? Он имеет несколько iirc.
2. Да, это то, что указано в java.util. Массивы;
3. Вот результат, который я вижу, когда смотрю на исходный код:
return new Arrays.ArrayList(a)
. Это не обычный ArrayList.4. Это другой класс, который просто случайно также вызывается
ArrayList
.5.
System.out.println(asList().getClass())
.
Ответ №1:
List
Возвращаемый Arrays.asList()
объект частично неизменяем. Некоторые операции мутации реализованы, другие — нет. В принципе, все операции, которые выполняют запись в базовый массив, реализованы. Операции, которые потребовали бы перераспределения нового массива, не реализованы. set()
например, реализовано, add()
нет. Если вам нужен правильный List
изменяемый во всех аспектах:
List<T> myList = asList(v1, v2, v3); // Immutable
List<T> myList = new ArrayList<>(asList(v1, v2, v3)); // Mutable
Объект, List
возвращаемый Arrays.asList()
, не является «нормальным» (java.util.)ArrayList
. Обычный объект ArrayList
может увеличиваться за счет перераспределения его резервного массива, что означает, что он является надлежащим, List
поддерживаемым массивом, но со всеми List
доступными функциями.
List
Возвращаемое Arrays.asList()
является « List
представлением» исходного массива. Он не может увеличиться, потому что это привело бы к потере ссылки на исходный массив. Следующий код демонстрирует это:
String[] data = { "foo", "bar" };
List<String> values = Arrays.asList(data);
System.err.println(values); // [foo, bar]
data[0] = "buzz";
values.set(1, "quak");
System.err.println(values); // [buzz, quak]
System.err.println(Arrays.toString(data)); // [buzz, quak]
Комментарии:
1. Это не изменчиво. Вызов
set()
вызовет исключение.2. Я беру его обратно, он изменяемый. Спасибо, что указали на это. Я не понимал, что это настолько непоследовательно.
3. Ya. Я искал здесь: hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share /…
4. Это не противоречит. В
Arrays.asList
документации говорится, что » возвращает список фиксированного размера, поддерживаемый указанным массивом «. Методыadd
иremove
по своей сути требуют списка переменного размера. Причина, по которой вы можете использоватьset
(иget
), заключается в том, что это похоже на доступ к массиву через индекс, за исключением того, что вместо массива этоList
. Это несколько объясняетсяAbstractList
: » Чтобы реализовать изменяемый список, [вы] должны дополнительно переопределить метод set(int, E) [. . .] Если список имеет переменный размер [вы] должны дополнительно переопределить методы add(int, E) и remove(int). «.5. @Slaw Спасибо за ваши указания, я соответствующим образом обновил ответ.