Нет публики:Маленькое кофейное шоу 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));
Результат вывода показан на следующем рисунке:
Затем добавьте элемент 3 в список состояний следующим образом:
statusList.add(3);
System.out.println(statusList.contains(3));
Ожидаемый результат должен быть правдой, но на самом деле он выброшенjava.lang.UnsupportedOperationException
аномальный:
Я не могу не задаться вопросом, почему такое исключение вызывается простым добавлением элемента.Это ненаучно.
1.2 Анализ причин
Имея в виду этот вопрос, давайте посмотримArrays
Исходный код статического метода asList, предоставленный классом:
то, что возвращаетсяArrayList
, очень знакомо, есть дрова, но если вы внимательно посмотрите, то обнаружите, что этот ArrayList не тот ArrayList, который мы часто используем, потому что мы обычно используемArrayList
находится вjava.util
Под пакетом:
Но здесьArrayList
но этоArrays
Внутренний класс класса:
он также наследуетAbstractList
класс, который переопределяет многие методы, такие как тот, который мы использовали вышеcontains
метод, но не переопределенныйadd
метод, поэтому мы вызываемadd
метод выдастjava.lang.UnsupportedOperationException
аномальный.
Что касается этого момента, он также упоминается в Taishan Edition «Руководства по разработке Java для Alibaba»:
При использовании служебного класса Arrays.asList() для преобразования массива в коллекцию вы не можете использовать его методы, связанные с изменением коллекций, а его методы добавления/удаления/очистки вызовут исключение UnsupportedOperationException.
Так все пользуютсяArrays.asList
Вы все равно должны быть внимательны, чтобы не наступить на яму.
1.3 Резюме
Arrays.asList
Методы можно использовать в некоторых простых ситуациях, таких как быстрое объявление коллекции, чтобы определить, находится ли значение в допустимом диапазоне:
Но не звоните снова после объявления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);
Результат работы показан на следующем рисунке:
Как видно из текущих результатов, subList возвращает набор элементов в bookList, чьи индексы находятся в диапазоне от индекса (включительно) до индекса (исключительно).
Он очень прост в использовании и понятен, но все же есть некоторые моменты, на которые стоит обратить внимание, иначе это вызовет программные ошибки или исключения:
- Изменение значения элемента исходной коллекции повлияет на подколлекцию.
- Изменение структуры исходной коллекции вызовет
ConcurrentModificationException
аномальный - Изменение значения элемента вложенной коллекции повлияет на исходную коллекцию.
- Изменение структуры подколлекции повлияет на исходную коллекцию.
Вышеупомянутые пункты описаны в Taishan Edition «Руководства по разработке Java для Alibaba»:
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);
Результат запуска следующий:
Видно, что хотя мы изменили только значение исходной коллекции 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);
Результат запуска следующий:
Видно, что когда мы добавляем элементы (структурные модификации) в исходную коллекцию, при обходе подколлекции что-то происходитConcurrentModificationException
аномальный.
Примечание. Указанное выше исключение возникает не при добавлении элементов, а при обходе вложенных коллекций после добавления элементов.
Это описано в Taishan Edition «Руководства по разработке Java для Alibaba»:
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);
Результат запуска следующий:
Можно видеть, что, хотя мы только изменили значение подколлекции 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);
Результат запуска следующий:
Видно, что когда мы добавляем элементы (структурные модификации) в подколлекцию, это влияет на исходную коллекцию bookList.
2.5 Анализ причин
Во-первых, давайте посмотрим наsubList
Аннотация метода для понимания его назначения:
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, исходный код конструктора показан на следующем рисунке:
Видно, что класс SubList является внутренним классом ArrayList, а конструктор не воссоздает новый ArrayList, поэтому изменение значения элементов исходной коллекции или вложенной коллекции повлияет друг на друга.
2.6 Резюме
Метод subList ArrayList возвращает подколлекцию (представление) исходной коллекции. Неструктурные изменения значения любого элемента коллекции будут влиять друг на друга. Когда исходная коллекция структурно изменена, она сообщитConcurrentModificationException
Исключение, при структурном изменении вложенной коллекции оно повлияет на исходную коллекцию, поэтому будьте осторожны при его использовании, чтобы избежать программных ошибок или исключений.
3. Ссылка
Используйте метод subList в ArrayList с осторожностью
«Руководство по разработке Java для Alibaba», издание Taishan