Рубрики
Без рубрики

Java ArrayList против вектора

Узнайте о различиях между классами Java ArrayList и Vector

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы сосредоточимся на различиях между классами ArrayList и Вектор /. Они оба принадлежат платформе Java Collections и реализуют java.util.Список интерфейс.

Однако эти классы имеют существенные различия в своих реализациях.

2. В чем разница?

Для быстрого начала давайте представим ключевые различия ArrayList и Vector. Затем мы обсудим некоторые моменты более подробно:

  • синхронизация – первое существенное различие между этими двумя. Вектор синхронизирован, а ArrayList нет.
  • рост размера – Еще одно различие между ними заключается в том, как они изменяют размер при достижении своей емкости. | Вектор удваивает свой размер. Напротив, ArrayList увеличивается только на половину своей длины итерация – И
  • Вектор может использовать Итератор и Перечисление для обхода элементов. С другой стороны, ArrayList может использовать только Итератор . производительность – В основном из-за синхронизации,
  • Вектор операции выполняются медленнее по сравнению с Список объектов фреймворк – Кроме того,
  • ArrayList является частью фреймворка коллекций и был представлен в JDK 1.2. Между тем, Вектор присутствует в более ранних версиях Java как устаревший класс.

3. Вектор

Поскольку у нас уже есть расширенное руководство по ArrayList, мы не будем обсуждать здесь его API и возможности. С другой стороны, мы представим некоторые основные сведения о Вектор .

Проще говоря , Вектор представляет собой массив с возможностью изменения размера . Он может расти и уменьшаться по мере добавления или удаления элементов.

Мы можем создать вектор типичным способом:

Vector vector = new Vector<>();

Конструктор по умолчанию создает пустой Вектор с начальной емкостью 10.

Давайте добавим несколько значений:

vector.add("baeldung");
vector.add("Vector");
vector.add("example");

И, наконец, давайте пройдемся по значениям с помощью интерфейса итератора:

Iterator iterator = vector.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    // ...
}

Или мы можем пересечь Вектор , используя Перечисление :

Enumeration e = vector.elements();
while(e.hasMoreElements()) {
    String element = e.nextElement();
    // ... 
}

Теперь давайте более подробно рассмотрим некоторые из их уникальных особенностей.

4. Параллелизм

Мы уже упоминали, что ArrayList и Вектор отличаются друг от друга стратегией параллелизма, но давайте рассмотрим ее поближе. Если бы мы погрузились в сигнатуры вектора метода, мы бы увидели, что у каждого из них есть ключевое слово synchronized:

public synchronized E get(int index)

Проще говоря, это означает, что только один поток может одновременно получить доступ к заданному вектору .

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

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

Например, мы можем использовать CopyOnWriteArrayList или Коллекции.synchronizedList для получения эффекта, аналогичного векторному :

vector.get(1); // synchronized
Collections.synchronizedList(arrayList).get(1); // also synchronized

5. Производительность

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

Чтобы увидеть разницу в производительности между операциями Vector и ArrayList , давайте напишем простой тест JMH/|.

В прошлом мы рассматривали временную сложность операций Arraylist , поэтому давайте добавим тестовые примеры для Vector.

Сначала , давайте протестируем метод get() :

@Benchmark
public Employee testGet(ArrayListBenchmark.MyState state) {
    return state.employeeList.get(state.employeeIndex);
}

@Benchmark
public Employee testVectorGet(ArrayListBenchmark.MyState state) {
    return state.employeeVector.get(state.employeeIndex);
}

Мы настроим JMH на использование трех потоков и 10 итераций прогрева.

И давайте сообщим о среднем времени на операцию на наносекундном уровне:

Benchmark                         Mode  Cnt   Score   Error  Units
ArrayListBenchmark.testGet        avgt   20   9.786 ± 1.358  ns/op
ArrayListBenchmark.testVectorGet  avgt   20  37.074 ± 3.469  ns/op

Мы видим, что ArrayList#get работает примерно в три раза быстрее, чем Вектор#get .

Теперь давайте сравним результаты операции contains() :

@Benchmark
public boolean testContains(ArrayListBenchmark.MyState state) {
    return state.employeeList.contains(state.employee);
}

@Benchmark
public boolean testContainsVector(ArrayListBenchmark.MyState state) {
    return state.employeeVector.contains(state.employee);
}

И распечатайте результаты:

Benchmark                              Mode  Cnt  Score   Error  Units
ArrayListBenchmark.testContains        avgt   20  8.665 ± 1.159  ns/op
ArrayListBenchmark.testContainsVector  avgt   20  36.513 ± 1.266  ns/op

Как мы видим, для операции contains() время выполнения Vector намного больше, чем ArrayList .

6. Краткое изложение

В этой статье мы рассмотрели различия между классами Vector и ArrayList в Java. Кроме того, мы также представили Векторные функции более подробно.

Как обычно, полный код этой статьи доступен на GitHub .