Вступление:
CopyOnWriteArrayList в Java является поточно- ориентированной реализацией интерфейса List . Он принадлежит пакету java.util.concurrent и является улучшенной версией реализации ArrayList .
Как следует из названия, CopyOnWriteArrayList создает клонированную внутреннюю копию базового ArrayList для каждой операции add () или set () . Из-за этих дополнительных накладных расходов в идеале мы должны использовать CopyOnWriteArrayList только тогда, когда у нас очень частые операции чтения, а не много вставок или обновлений.
Построение CopyOnWriteArrayList :
Мы можем использовать один из следующих конструкторов для создания CopyOnWriteArrayList :
- CopyOnWriteArrayList (): создает пустой список
- CopyOnWriteArrayList (Collection c): создает список, инициализированный со всеми элементами в c
- CopyOnWriteArrayList (Object [] obj): создает список, содержащий копию данного массива obj
Давайте посмотрим на несколько примеров:
Ява
01
02
03
04
05
06
07
08
09
10
|
CopyOnWriteArrayList<String> emptyList = new CopyOnWriteArrayList<>(); //[] list.add( "A" ); CopyOnWriteArrayList<String> listUsingCollection = new CopyOnWriteArrayList<>(list); //["A"] CopyOnWriteArrayList<String> listUsingArr = new CopyOnWriteArrayList<>( new String[] { "A" , "B" }); //["A", "B"] |
Как и ArrayList , он предоставляет реализации для всех методов интерфейса List . Мы можем прочитать больше о ArrayList здесь.
Вставка и итерация над CopyOnWriteArrayList :
Как мы знаем, итератор ArrayList является отказоустойчивым, то есть он генерирует исключение ConcurrentModificationException при обнаружении любой модификации в списке после создания экземпляра итератора.
CopyOnWriteArrayList имеет отказоустойчивый итератор и не выдает исключение, даже когда мы изменяем список во время его итерации. Это потому, что итератор работает над клонированной внутренней копией исходного списка.
Однако любые изменения, внесенные позже в список, не будут видны уже созданному итератору.
Давайте попробуем это
Допустим, у нас есть экземпляр CopyOnWriteArrayList, который в настоящее время содержит два элемента:
Ява
1
2
|
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>( new String[] { "A" , "B" }); |
Теперь давайте возьмем экземпляр Iterator, чтобы мы могли перебирать его элементы:
Ява
1
|
Iterator itr = list.iterator(); |
После того, как мы создали экземпляр Iterator , давайте теперь добавим еще один элемент в наш список:
Ява
1
2
|
list.add( "C" ); //doesn't throw an exception |
Теперь давайте пройдемся по элементам нашего списка, используя itr , который мы создали ранее:
Ява
1
2
3
|
while (itr.hasNext()) { System.out.print(itr.next() + " " ); } |
Код выше напечатает:
1
2
|
A B |
Как и ожидалось, itr не отражает текущее состояние списка и печатает только «A» и «B» в качестве его элементов. Однако, если мы создадим новый экземпляр итератора, он будет представлять точное текущее состояние списка.
Удаление и итерация над CopyOnWriteArrayList :
Итератор CopyOnWriteArrayList не поддерживает операцию удаления () . Любая попытка сделать это приведет к исключению UnsupportedOperationException:
Ява
01
02
03
04
05
06
07
08
09
10
11
|
@Test (expected = UnsupportedOperationException. class ) public void iterationAndRemoval() { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>( new String[]{ "A" , "B" }); Iterator<String> itr = list.iterator(); while (itr.hasNext()) { itr.remove(); } } |
ArrayList vs CopyOnWriteArrayList:
Давайте рассмотрим различия между классами Java ArrayList и CopyOnWriteArrayList :
ArrayList | CopyOnWriteArrayList |
---|---|
Принадлежит к пакету java.util и не является потокобезопасным | Поточно-ориентированная реализация, присутствующая в пакетах java.util.concurrent. |
Имеет отказоустойчивый итератор, который генерирует исключение ConcurrentModificationException при обнаружении любой модификации после начала итерации | Имеет отказоустойчивый итератор, поскольку итератор содержит клонированную копию списка |
Итератор поддерживает операцию удаления () | Его итератор не поддерживает remove () и выдает исключение UnsupportedOperationException при любой попытке сделать это |
Вывод:
В этом уроке мы узнали о поточно- ориентированной реализации Java List — CopyOnWriteArrayList . Мы также рассмотрели разницу между ArrayList и CopyOnWriteArrayList .
Оставьте первый комментарий.
Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Смотреть оригинальную статью здесь: CopyOnWriteArrayList В Java Мнения, высказанные участниками Java Code Geeks, являются их собственными. |