Arrays.asList и subList ArrayList использовались в проекте и подверглись публичной критике.

Java

Нет публики:Маленькое кофейное шоу Java,Веб-сайт:javaxks.com

Автор: Stranger in Shencheng, ссылка:blog.CSDN.net/Где Ухань/искусство…

1. Примечания по использованию Arrays.asList

1.1 Возможные ямы, на которые можно наступить

Давайте взглянемArrays.asListиспользование:

List<Integer> statusList = Arrays.asList(1, 2);
System.out.println(statusList);
System.out.println(statusList.contains(1));
System.out.println(statusList.contains(3));

Результат вывода показан на следующем рисунке:

img

Затем добавьте элемент 3 в список состояний следующим образом:

statusList.add(3);
System.out.println(statusList.contains(3));

Ожидаемый результат должен быть правдой, но на самом деле он выброшенjava.lang.UnsupportedOperationExceptionаномальный:

img

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

1.2 Анализ причин

Имея в виду этот вопрос, давайте посмотримArraysИсходный код статического метода asList, предоставленный классом:

img

то, что возвращаетсяArrayList, очень знакомо, есть дрова, но если вы внимательно посмотрите, то обнаружите, что этот ArrayList не тот ArrayList, который мы часто используем, потому что мы обычно используемArrayListнаходится вjava.utilПод пакетом:

img

Но здесьArrayListно этоArraysВнутренний класс класса:

img

img

он также наследуетAbstractListкласс, который переопределяет многие методы, такие как тот, который мы использовали вышеcontainsметод, но не переопределенныйaddметод, поэтому мы вызываемaddметод выдастjava.lang.UnsupportedOperationExceptionаномальный.

Что касается этого момента, он также упоминается в Taishan Edition «Руководства по разработке Java для Alibaba»:

При использовании служебного класса Arrays.asList() для преобразования массива в коллекцию вы не можете использовать его методы, связанные с изменением коллекций, а его методы добавления/удаления/очистки вызовут исключение UnsupportedOperationException.

img

Так все пользуютсяArrays.asListВы все равно должны быть внимательны, чтобы не наступить на яму.

1.3 Резюме

Arrays.asListМетоды можно использовать в некоторых простых ситуациях, таких как быстрое объявление коллекции, чтобы определить, находится ли значение в допустимом диапазоне:

img

Но не звоните снова после объявленияaddи другие методы для изменения коллекции, иначе она сообщитjava.lang.UnsupportedOperationExceptionаномальный.

2. Примечания по использованию подсписка ArrayList

Давайте посмотрим на простое использование subList:

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

Результат работы показан на следующем рисунке:

img

Как видно из текущих результатов, subList возвращает набор элементов в bookList, чьи индексы находятся в диапазоне от индекса (включительно) до индекса (исключительно).

Он очень прост в использовании и понятен, но все же есть некоторые моменты, на которые стоит обратить внимание, иначе это вызовет программные ошибки или исключения:

  1. Изменение значения элемента исходной коллекции повлияет на подколлекцию.
  2. Изменение структуры исходной коллекции вызоветConcurrentModificationExceptionаномальный
  3. Изменение значения элемента вложенной коллекции повлияет на исходную коллекцию.
  4. Изменение структуры подколлекции повлияет на исходную коллекцию.

Вышеупомянутые пункты описаны в Taishan Edition «Руководства по разработке Java для Alibaba»:

img

2.1 Изменение значения исходной коллекции повлияет на вложенную коллекцию

Например, мы изменяем значение элемента в исходной коллекции bookList (неструктурные модификации):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 修改原集合的值
bookList.set(3,"路遥-人生");

System.out.println(bookList);
System.out.println(luyaoBookList);

Результат запуска следующий:

img

Видно, что хотя мы изменили только значение исходной коллекции bookList, это повлияло на подколлекцию luyaoBookList.

2.2 Изменение структуры исходной коллекции вызоветConcurrentModificationExceptionаномальный

Например, мы добавляем элемент в исходную коллекцию bookList (Структурная модификация):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 往原集合中添加元素
bookList.add("早晨从中午开始");

System.out.println(bookList);
System.out.println(luyaoBookList);

Результат запуска следующий:

img

Видно, что когда мы добавляем элементы (структурные модификации) в исходную коллекцию, при обходе подколлекции что-то происходитConcurrentModificationExceptionаномальный.

Примечание. Указанное выше исключение возникает не при добавлении элементов, а при обходе вложенных коллекций после добавления элементов.

Это описано в Taishan Edition «Руководства по разработке Java для Alibaba»:

img

2.3 Изменение значения подколлекции повлияет на исходную коллекцию

Например, мы модифицируем значение элемента в подколлекции luyaoBookList (неструктурные модификации):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 修改子集合的值
luyaoBookList.set(1,"路遥-平凡的世界");

System.out.println(bookList);
System.out.println(luyaoBookList);

Результат запуска следующий:

img

Можно видеть, что, хотя мы только изменили значение подколлекции luyaoBookList, это повлияло на исходную коллекцию bookList.

2.4 Изменение структуры подколлекции повлияет на исходную коллекцию

Например, мы добавляем элемент в подколлекцию luyaoBookList (Структурная модификация):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 往子集合中添加元素
luyaoBookList.add("早晨从中午开始");

System.out.println(bookList);
System.out.println(luyaoBookList);

Результат запуска следующий:

img

Видно, что когда мы добавляем элементы (структурные модификации) в подколлекцию, это влияет на исходную коллекцию bookList.

2.5 Анализ причин

Во-первых, давайте посмотрим наsubListАннотация метода для понимания его назначения:

img

Returns a view of the portion of this list between the specified {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.

В переводе это означает:

Возвращает представление части списка между указанным {@code fromIndex} (включительно) и {@code toIndex} (исключительно).

Затем давайте посмотрим на его исходный код:

public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}

Как видите, он вызывает конструктор класса SubList, исходный код конструктора показан на следующем рисунке:

img

Видно, что класс SubList является внутренним классом ArrayList, а конструктор не воссоздает новый ArrayList, поэтому изменение значения элементов исходной коллекции или вложенной коллекции повлияет друг на друга.

2.6 Резюме

Метод subList ArrayList возвращает подколлекцию (представление) исходной коллекции. Неструктурные изменения значения любого элемента коллекции будут влиять друг на друга. Когда исходная коллекция структурно изменена, она сообщитConcurrentModificationExceptionИсключение, при структурном изменении вложенной коллекции оно повлияет на исходную коллекцию, поэтому будьте осторожны при его использовании, чтобы избежать программных ошибок или исключений.

3. Ссылка

Используйте метод subList в ArrayList с осторожностью

«Руководство по разработке Java для Alibaba», издание Taishan