Какие знаешь реализации, кроме ArrayList и LinkedList?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Реализации интерфейса List в Java
В Java есть много реализаций List помимо ArrayList и LinkedList. Каждая имеет свои характеристики, применение и граничные случаи.
1. Vector (класс из древности)
Это устаревший синхронизированный аналог ArrayList:
Vector<String> vector = new Vector<>();
vector.add("item");
vector.addElement("another");
Характеристики:
- Полностью синхронизирован (все методы synchronized)
- Медленнее ArrayList из-за overhead синхронизации
- Использовать не рекомендуется, лучше Collections.synchronizedList()
2. CopyOnWriteArrayList
Типичное решение для многопоточных сценариев с частым чтением:
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("item1");
list.add("item2");
// Итерация не требует синхронизации
for (String item : list) {
System.out.println(item);
}
Как работает:
- При записи копирует весь массив
- При чтении нет блокировок
- Оптимален для сценариев типа listeners, observers
- Дорогой в памяти при частых записях
3. UnmodifiableList (immutable список)
List<String> original = new ArrayList<>(Arrays.asList("a", "b", "c"));
List<String> immutable = Collections.unmodifiableList(original);
immutable.add("d"); // UnsupportedOperationException
Использование:
- Защита от нежелательных изменений
- Thread-safe по определению (не может измениться)
4. SynchronizedList
Полностью синхронизированный список:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
syncList.add("item");
Особенность: нужно синхронизировать итерацию вручную:
synchronized(syncList) {
for (String item : syncList) {
System.out.println(item);
}
}
5. Подклассы AbstractList
AbstractList — базовый класс для создания custom List реализаций:
class RangeList extends AbstractList<Integer> {
private int size;
public RangeList(int size) { this.size = size; }
@Override
public Integer get(int index) {
if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
return index;
}
@Override
public int size() { return size; }
}
// Использование
List<Integer> range = new RangeList(10);
System.out.println(range.get(5)); // 5
6. Списки из массивов
Arrays.asList() — возвращает фиксированный размер List:
List<String> list = Arrays.asList("a", "b", "c");
list.set(0, "x"); // OK
list.add("d"); // UnsupportedOperationException
List.of() (Java 9+) — immutable копия:
List<String> list = List.of("a", "b", "c");
list.add("d"); // UnsupportedOperationException
7. SubList
Представление подмножества существующего списка:
List<String> original = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
List<String> sublist = original.subList(1, 3); // [b, c]
sublist.set(0, "B");
System.out.println(original); // [a, B, c, d] — изменения синхронизированы
8. Стриммовые операции
Можно собрать результаты в список разными способами:
List<String> list1 = Stream.of("a", "b", "c")
.collect(Collectors.toList());
List<String> list2 = Stream.of("a", "b", "c")
.collect(Collectors.toUnmodifiableList());
Сравнение
| Класс | Thread-safe | Производительность | Использование |
|---|---|---|---|
| ArrayList | Нет | Высокая | Базовый случай |
| LinkedList | Нет | Средняя | Удаления в начале |
| Vector | Да | Низкая | Избегать |
| CopyOnWriteArrayList | Да | Хорошая на чтение | Много читателей, мало писателей |
| UnmodifiableList | Да | Высокая | Константные данные |
| AbstractList | Переопределять | Зависит | Custom реализации |
Выбор зависит от сценария: нужна ли синхронизация, как часто читаем/пишем, какие операции доминируют.