Как создать новый список (List) в Java: ArrayList, LinkedList и другие варианты
Почему нельзя создать List напрямую?
List — это не класс, а интерфейс (как контракт). Он описывает, какие методы должны быть у списка (add, get, remove и т.д.), но не содержит реализации. Поэтому new List() вызывает ошибку компиляции — вы не можете создать объект интерфейса. Вместо этого вы создаете объект класса, который реализует этот интерфейс.
Основные реализации List в Java
Самые популярные реализации — ArrayList и LinkedList. Вот их ключевые различия:
- ArrayList — основан на обычном массиве. Быстрый доступ по индексу (O(1)), но медленная вставка/удаление в середине (O(n)). Идеален, когда вы часто читаете элементы.
- LinkedList — основан на двусвязном списке. Быстрая вставка/удаление в начале или середине (O(1) для операций с краями), но медленный доступ по индексу (O(n)). Хорош для очередей и частых изменений.
Способы создания списка
Вот основные варианты с примерами кода:
import java.util.*;
public class ListExamples {
public static void main(String[] args) {
// 1. Классический способ
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");
// 2. LinkedList
List<Integer> linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);
// 3. Сразу с элементами (Java 9+)
List<String> immutableList = List.of("A", "B", "C");
// Внимание: такой список НЕЛЬЗЯ изменять!
// 4. Arrays.asList (возвращает список фиксированного размера)
List<String> fixedList = Arrays.asList("X", "Y", "Z");
// Можно менять элементы, но нельзя добавлять/удалять
// 5. Двойная инициализация (не рекомендуется, но встречается)
List<String> doubleBrace = new ArrayList<>() {{
add("One");
add("Two");
}};
// 6. Через Collections (для одного элемента)
List<String> singleton = Collections.singletonList("Only");
// 7. Копирование из другой коллекции
List<String> copy = new ArrayList<>(arrayList);
// 8. Пустой неизменяемый список
List<String> empty = Collections.emptyList();
}
}
Как выбрать правильный список?
Вот простая шпаргалка:
- ✔️ 95% случаев — используйте
ArrayList. Он быстрее всего для типичных задач. - ✔️ Если часто вставляете/удаляете в начале —
LinkedList. - ✔️ Если нужен неизменяемый список-константа —
List.of(). - ❌ Избегайте
Vector— это устаревший синхронизированный аналог ArrayList.
Важные замечания для новичков
- Всегда объявляйте переменную как
List<T>, а не какArrayList<T>. Это дает гибкость: вы можете легко заменить реализацию. - Не забывайте про дженерики (угловые скобки).
Listбез типа — плохая практика. - Метод
List.of()возвращает неизменяемый список. Попытка изменить его вызоветUnsupportedOperationException.
Надеюсь, теперь стало понятнее! Главное запомнить: List — это интерфейс, а ArrayList — самая популярная его реализация.
Альтернативный взгляд: когда использовать другие коллекции
Первый ответ отлично объясняет базовые варианты. Я хочу добавить про менее очевидные ситуации, где ArrayList или LinkedList могут быть не лучшим выбором.
1. Если вам нужен список с уникальными элементами
Используйте Set (например, HashSet или TreeSet), а не List. Вы избежите дубликатов:
Set<String> uniqueNames = new HashSet<>();
uniqueNames.add("Анна");
uniqueNames.add("Анна"); // не добавится второй раз
2. Если нужен список с быстрым поиском по ключу
Рассмотрите Map (например, HashMap). Вместо списка объектов с полем "id" лучше хранить Map<Integer, User>.
3. Если вам нужна потокобезопасность
ArrayList не потокобезопасен. В многопоточном коде используйте:
CopyOnWriteArrayList— для редких изменений, частого чтения.Collections.synchronizedList(new ArrayList<>())— для общей синхронизации.
4. Если работаете с большими данными и производительность критична
Иногда ArrayList неэффективен из-за частого расширения. Задайте начальную емкость:
List<String> bigList = new ArrayList<>(1_000_000); // сразу выделяем память
Помните: выбор коллекции — это компромисс между скоростью операций и памятью. Для 90% задач ArrayList — золотой стандарт, но всегда анализируйте конкретные требования.