Arrays.asList () сомневаешься? - PullRequest
       0

Arrays.asList () сомневаешься?

16 голосов
/ 25 января 2011

Люди говорят, что метод asList преобразует массив в список и не копирует его, поэтому каждое изменение в 'aList' будет отражаться в 'a'. Поэтому добавление новых значений в 'aList' недопустимо, поскольку массив имеет фиксированный размер.

Но, asList() метод возвращает ArrayList<T>. Как компилятор отличает строку 3 от 5. Строка 3 дает мне исключение (UnsupportedOperationException).

        String[] a = {"a","b","c","d"};//1
        List<String> aList =  Arrays.asList(a);//2
        aList.add("e");//3
        List<String> b = new ArrayList<String>();//4
        b.add("a");//5

Ответы [ 8 ]

35 голосов
/ 25 января 2011

Эта реализация List, которую вы получаете от Arrays.asList, представляет собой особый вид массива - вы не можете изменить его размер.

Тип возврата Arrays.asList() - java.util.Arrays.ArrayList, который часто путают с java.util.ArrayList. Arrays.ArrayList просто показывает массив в виде списка .

9 голосов
/ 25 января 2011

Прочтите еще раз , тип Arrays.asList:

public static <T> List<T> asList(T... a)

, в котором четко указано, что asList возвращает объект, реализующий интерфейс java.util.List нигде не говорит, что вернет экземпляр класса java.util.ArrayList .

Далее, обратите внимание, что документация по List.add гласит:

логическое добавление (E e)

Добавляет указанный элемент в конец этого списка (необязательная операция) .

Технически, каждый раз, когда вы используете переменную, типизированную как List (вместо ArrayList), вы всегда должны быть осторожны, ожидая, что этот метод может выдать UnsupportedOperationException.Если вы уверены, что получите только реализацию List, которая всегда имеет правильную семантику .add(), то вы можете пропустить проверку, рискуя ошибкой, когда ваше предположение будет недействительным.

5 голосов
/ 05 января 2012

Manoj,

Тип возврата Arrays.List - это неизвестная внутренняя реализация интерфейса List, а not java.util.ArrayList, поэтому вы можете назначить его только списку.type.

Если вы назначите его, например, для ArrayList, это даст вам ошибку времени компиляции "Несоответствие типов: невозможно преобразовать из List в ArrayList"

  ArrayList<String> aList =  Arrays.asList(a);// gives Compile time error

Из Javadoc "Arrays.asList Возвращает список фиксированного размера, за которым стоит заданный массив. (Изменения в возвращенном списке" записывают "в массив.)", Что означает, что вам предоставляется только представление списка массива, IMOсоздается во время выполнения и, конечно, вы не можете изменить размер массива, поэтому вы также не можете изменить размер «Arrays.asList».

IMO внутренняя реализация Arrays.asList имеет все реализованные методы, которые могутизмените размер массива как -

void add(E e)
{
//some unknown code
throw(java.lang.UnsupportedOperationException);
}

, поэтому всякий раз, когда вы пытаетесь изменить размер массива, он генерирует исключение UnsupportedOperationException.

StЕсли вы хотите добавить некоторые новые элементы в ArrayList с помощью такого синтаксиса, вы можете сделать это, создав подкласс Arraylist (предпочтительно используя анонимный подкласс ArrayList).Вы можете передать возвращаемый тип Arrays.List в конструктор ArrayList (т.е. public ArrayList (Collection c)) примерно так:

List<String> girlFriends = new java.util.ArrayList<String>(Arrays.asList("Rose", "Leena", "Kim", "Tina"));
girlFriends.add("Sarah");

Теперь вы можете легко добавить Сару в свой список GF, используятот же синтаксис.

PS - Пожалуйста, выберите этот или другой в качестве ответа, потому что все было объяснено.Ваш низкий уровень принятия очень обескураживает.

4 голосов
/ 25 января 2011

asList() не возвращает java.util.ArrayList, возвращается java.util.Arrays$ArrayList. Этот класс даже не расширяет java.util.ArrayList, поэтому его поведение может быть (и есть) совершенно другим.

Метод add() унаследован от java.util.AbstractList, который по умолчанию просто выбрасывает UnsupportedOperationException.

3 голосов
/ 25 января 2011

Вы предполагаете, что Arrays.asList() возвращает ArrayList, но это не так.Arrays.asList() возвращает неопределенную List реализацию.Эта реализация просто бросает UnsupportedOperationException на каждый неподдерживаемый метод.

3 голосов
/ 25 января 2011

Это исключение, а не ошибка компилятора. Выдается при запуске программы, а не во время компиляции. По сути, фактический класс, который будет возвращать Arrays.asList, имеет throw UnsupporteOperationException внутри метода add().

Чтобы быть более точным, Arrays.asList вернет внутренний класс, определенный внутри класса Arrays, который получен из AbstractList и не реализует метод add. Метод add из AbstractList фактически вызывает исключение.

1 голос
/ 25 января 2011

Ключом к этому является реализация List, возвращаемая

List<String> aList =  Arrays.asList(a);

Если вы посмотрите на исходный код в Arrays, вы увидите, что он содержит внутренний закрытый статический класс ArrayList.Это не то же самое, что java.util.ArrayList.

0 голосов
/ 25 января 2011

asList возвращает список фиксированного размера, поэтому вы не можете добавлять в него новые элементы. Поскольку список, который он возвращает, на самом деле является «представлением» массива, из которого он был создан («a» в вашем случае), имеет смысл, что вы не сможете добавлять элементы - так же, как вы не можете добавлять элементы в массив. См. Документы для asList

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...