Руководство по Java ArrayList

Руководство по Java ArrayList

1. обзор

В этой статье мы рассмотрим классArrayList из Java Collections Framework. Мы обсудим его свойства, распространенные варианты использования, а также его преимущества и недостатки.

ArrayList находится в библиотеках Java Core, поэтому вам не нужны дополнительные библиотеки. Чтобы использовать его, просто добавьте следующий оператор импорта:

import java.util.ArrayList;

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

ArrayList - одна из реализацийList, построенная на основе массива, который может динамически увеличиваться и уменьшаться по мере добавления / удаления элементов. Элементы могут быть легко доступны по их индексам, начиная с нуля. Эта реализация имеет следующие свойства:

  • Произвольный доступ занимаетO(1) времени

  • Добавление элемента занимает амортизированное постоянное времяO(1)с

  • Inserting/Deleting takes O(n) time

  • Поиск занимаетO(n) для несортированного массива иO(log n) для отсортированного.

2. СоздайтеArrayList

ArrayList имеет несколько конструкторов, и мы представим их все в этом разделе.

Во-первых, обратите внимание, чтоArrayList - это общий класс, поэтому вы можете параметризовать его любым типом, который хотите, и компилятор гарантирует, что, например, вы не сможете помещать значенияInteger в коллекцию Strings. Кроме того, вам не нужно приводить элементы при извлечении их из коллекции.

Во-вторых, рекомендуется использовать общий интерфейсList в качестве типа переменной, поскольку он отделяет его от конкретной реализации.

2.1. Конструктор без аргументов по умолчанию

List list = new ArrayList<>();
assertTrue(list.isEmpty());

Мы просто создаем пустой экземплярArrayList.

2.2. Конструктор принимает начальную емкость

List list = new ArrayList<>(20);

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

2.3. Конструктор принимаетCollection

Collection number
  = IntStream.range(0, 10).boxed().collect(toSet());

List list = new ArrayList<>(numbers);
assertEquals(10, list.size());
assertTrue(numbers.containsAll(list));

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

3. Добавить элементы вArrayList

Вы можете вставить элемент в конце или в определенной позиции:

List list = new ArrayList<>();

list.add(1L);
list.add(2L);
list.add(1, 3L);

assertThat(Arrays.asList(1L, 3L, 2L), equalTo(list));

Вы также можете вставить коллекцию или несколько элементов одновременно:

List list = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
LongStream.range(4, 10).boxed()
  .collect(collectingAndThen(toCollection(ArrayList::new), ys -> list.addAll(0, ys)));
assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(list));

4. Итерировать черезArrayList

Доступны два типа итераторов:Iterator иListIterator.

В то время как первый дает вам возможность перемещаться по списку в одном направлении, второй позволяет перемещаться по нему в обоих направлениях.

Здесь мы покажем вам толькоListIterator:

List list = new ArrayList<>(
  IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new))
);
ListIterator it = list.listIterator(list.size());
List result = new ArrayList<>(list.size());
while (it.hasPrevious()) {
    result.add(it.previous());
}

Collections.reverse(list);
assertThat(result, equalTo(list));

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

5. НайдитеArrayList

Мы покажем, как работает поиск с использованием коллекции:

List list = LongStream.range(0, 16)
  .boxed()
  .map(Long::toHexString)
  .collect(toCollection(ArrayList::new));
List stringsToSearch = new ArrayList<>(list);
stringsToSearch.addAll(list);

5.1. Поиск в несортированном списке

Чтобы найти элемент, вы можете использовать методыindexOf() илиlastIndexOf(). Оба они принимают объект и возвращают значениеint:

assertEquals(10, stringsToSearch.indexOf("a"));
assertEquals(26, stringsToSearch.lastIndexOf("a"));

Если вы хотите найти все элементы, удовлетворяющие предикату, вы можете отфильтровать коллекцию, используя Java 8Stream API (подробнее об этомhere), используяPredicate следующим образом:

Set matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));

List result = stringsToSearch
  .stream()
  .filter(matchingStrings::contains)
  .collect(toCollection(ArrayList::new));

assertEquals(6, result.size());

Также можно использовать циклfor или итератор:

Iterator it = stringsToSearch.iterator();
Set matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));

List result = new ArrayList<>();
while (it.hasNext()) {
    String s = it.next();
    if (matchingStrings.contains(s)) {
        result.add(s);
    }
}

5.2. Поиск в отсортированном списке

Если у вас есть отсортированный массив, вы можете использовать алгоритм двоичного поиска, который работает быстрее, чем линейный поиск:

List copy = new ArrayList<>(stringsToSearch);
Collections.sort(copy);
int index = Collections.binarySearch(copy, "f");
assertThat(index, not(equalTo(-1)));

Обратите внимание, что если элемент не найден, то возвращается -1.

6. Удалить элементы изArrayList

Чтобы удалить элемент, необходимо найти его индекс и только после этого выполнить удаление с помощью методаremove(). Перегруженная версия этого метода, которая принимает объект, ищет его и выполняет удаление первого вхождения равного элемента:

List list = new ArrayList<>(
  IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new))
);
Collections.reverse(list);

list.remove(0);
assertThat(list.get(0), equalTo(8));

list.remove(Integer.valueOf(0));
assertFalse(list.contains(0));

Но будьте осторожны при работе с упакованными типами, такими какInteger. Чтобы удалить конкретный элемент, вы должны сначала указать значениеint, иначе элемент будет удален по его индексу.

Вы также можете использовать вышеупомянутыйStream API для удаления нескольких элементов, но мы не будем показывать его здесь. Для этого мы будем использовать итератор:

Set matchingStrings
 = HashSet<>(Arrays.asList("a", "b", "c", "d", "e", "f"));

Iterator it = stringsToSearch.iterator();
while (it.hasNext()) {
    if (matchingStrings.contains(it.next())) {
        it.remove();
    }
}

7. Резюме

В этой быстрой статье мы взглянули на ArrayList в Java.

Мы показали, как создать экземплярArrayList, как добавлять, находить или удалять элементы, используя разные подходы.

Как обычно, вы можете найти все образцы кодаover on GitHub.