Списки — Java: Коллекции
List в java – это интерфейс, который предоставляет возможность поддерживать упорядоченную коллекцию. Он содержит основанные на индексах методы для вставки, обновления, удаления и поиска элементов. Он также может иметь повторяющиеся элементы.
ArrayList
Класс ArrayList – реализация интерфейса List . Представляет собой автоматически расширяемый массив. ArrayList может менять свой размер во время исполнения программы
// Создаем новый экземпляр ArrayList ListString> list = new ArrayList<>(); System.out.println(list); // => [] // Добавляем элементы в список list.add("1"); list.add(null); list.add(null); list.add("2"); list.add("3"); list.add("3"); System.out.println(list); //=> [1, null, null, 2, 3, 3] list.remove(0); System.out.println(list); // => [null, null, 2, 3, 3] list.remove("3"); list.remove("4"); System.out.println(list); // => [null, null, 2, 3] System.out.println(list.size()); // => 4 ListString> insertedList = new ArrayList<>(); insertedList.add("1"); insertedList.add("2"); insertedList.add("7"); insertedList.add("7"); System.out.println(insertedList); // => [1, 2, 7, 7] list.addAll(2, insertedList); System.out.println(list); // => [null, null, 1, 2, 7, 7, 2, 3] System.out.println(list.indexOf("7")); // => 4 System.out.println(list.get(3)); // => 2 System.out.println(list.isEmpty()); // => false System.out.println(list.contains("2")); // => true System.out.println(list.contains("11")); // => false for (String s : list) System.out.println("element of list: " + s); >
// Создаем новую переменную с типом ArrayList ArrayListString> arrayList = (ArrayListString>) list; System.out.println(arrayList); // => [null, null, 1, 2, 7, 7, 2, 3]
LinkedList
Класс LinkedList — еще одна реализация интерфейса List . Представляет из себя двусвязный список, где каждый элемент структуры содержит ссылки на предыдущий и следующий элементы. По этим ссылкам можно переходить от одного элемента к другому.
// Создаем новый экземпляр двусвязного списка ListInteger> list = new LinkedList<>(); // Добавляем/удаляем элементы list.add(1); list.add(2); list.add(null); list.add(3); list.add(4); list.remove(1); list.add(null); System.out.println(list); // => [1, null, 3, 4, null] System.out.println(list.size()); // => 5 System.out.println(list.get(0)); // => 1 System.out.println(list.indexOf(3)); // => 2 LinkedListInteger> linkedList = (LinkedListInteger>) list; // Получаем, но не удаляем первый элемент списка System.out.println(linkedList.peek()); // => 1 System.out.println(list); // => [1, null, 3, 4, null] // Получаем и удаляем первый элемент списка System.out.println(linkedList.poll()); // => 1 System.out.println(linkedList); // => [null, 3, 4, null] // Вставляем элемент в начало списка linkedList.addFirst(3); System.out.println(linkedList); // => [3, null, 3, 4, null] for (Integer num: linkedList) System.out.println("int: " + num); >
Интерфейс List и класс ArrayList
Интерфейс List сохраняет последовательность добавления элементов и позволяет осуществлять доступ к элементу по индексу. Он расширяет интерфейс Collection и таким образом наследует все его методы, и вместе с тем добавляет свои методы:
- void add(int index, Е obj) — вставляет obj в вызывающий список в позицию, указанную в index . Любые ранее вставленные элементы за указанной позицией вставки смещаются вверх. То есть никакие элементы не перезаписываются.
- bооlеаn addAll (int index, Collection с) — в ставляет все элементы в вызывающий список, начиная с позиции, переданной в index . Все ранее существовавшие элементы за точкой вставки смещаются вверх. То есть никакие элементы не перезаписываются. Возвращает true , если вызывающий список изменяется, и false в противном случае.
- Е get (int index) — возвращает объект, сохраненный в указанной позиции вызывающего списка.
- int indexOf(Object obj) — возвращает индекс первого экземпляра obj в вызывающем списке. Если obj не содержится в списке, возвращается 1.
- int lastlndexOf(Object obj) — возвращает индекс последнего экземпляра obj в вызывающем списке. Если obj не содержится в списке, возвращается 1.
- Listlterator listlterator() — возвращает итератор, указывающий на начало списка.
- Listlterator listlterator(int index) — возвращает итератор, указывающий на заданную позицию в списке.
- Е remove(int index) — удаляет элемент из вызывающего списка в позиции index и возвращает удаленный элемент. Результирующий список уплотняется, то есть элементы, следующие за удаленным, сдвигаются на одну позицию назад.
- Е set (int index, Е obj) — присваивает obj элементу, находящемуся в списке в позиции index.
- default void sort(Comparator c) — сортирует список, используя заданный компаратор (добавлен в версии JDK 8).
- List subList (int start, int end) — возвращает список, включающий элементы от start до end-1 из вызывающего списка. Элементы из возвращаемого списка также сохраняют ссылки в вызывающем списке.
Если посмотреть на методы интерфейса List более внимательно, можно заметить, что почти все их них манипулируют индексом элемента.
Структура иерархии интерфейса List :

2. Особенности класса ArrayList
Одной из реализаций интерфейса List является класс ArrayList . Он поддерживает динамические массивы, которые могут расти по мере необходимости. Элементы ArrayList могут быть абсолютно любых типов, в том числе и null. Элементы в этом виде коллекции могут повторяться.
Данный класс используется чаще всех остальных реализаций коллекции.
Внутреннее устройство класса
Давайте начнем изучение этого класса с рассмотрения его внутреннего устройства, что важно для понимания при выборе класса коллекции.
Объект класса ArrayList , содержит свойства elementData и size . Хранилище значений elementData есть не что иное, как массив определенного типа (указанного в generic). По умолчанию размер этого внутреннего массива будет иметь размер 16 (при создании класса конструктором без параметров). Если пользователь добавит в ArrayList больше 16 элементов, ничего плохого не произойдет (в отличие от массивов, где будет выброшено ArrayIndexOutOfBoundsException исключение). В этом случае просто произойдет пересоздание внутреннего массива elementData , и это произойдет неявно для пользователя.
В случае если вы заранее знаете максимальное количество элементов в создаваемой коллекции, размер массива можно указать передав нужное значение в конструктор ArrayList . Такая программа не будет тратить ресурсы на пересоздание внутреннего массива и конечно же будет работать немного быстрее.
Конструкторы класса
У этого класса есть следующие конструкторы:
- ArrayList() — помогает создать пустую коллекцию с внутренним массивом размер которого будет 16.
- ArrayList(Collection сollection) — создает коллекцию и заполняет ее элементами из передаваемой коллекции collection.
- ArrayList(int capacity) — помогает создать пустую коллекцию с внутренним массивом, размер которого будет равен значению параметра capacity .
Из внутреннего устройства класса следуют его достоинства и недостатки. Рассмотрим их.
Достоинства класса ArrayList
- Быстрый доступ по индексу. Скорость такой операции — O(1).
- Быстрая вставка и удаление элементов с конца. Скорость операций опять же — O(1).
Недостатки класса ArrayList
- Медленная вставка и удаление элементов из середины. Такие операции имеют сложность O(n). Поэтому, если вы понимаете, что вам придется выполнять достаточно много операций такого типа, может быть лучше выбрать другой класс.
3. Добавления элементов в класс ArrayList
Для удобства в следующем списке приведены все методы, позволяющие добавлять элементы в объект класса ArrayList :
- boolean add(E obj) — добавляет obj к вызывающей коллекции. Возвращает true, если obj был добавлен к коллекции. (Интерфейс Collection )
- void add(int index, Е obj) — вставляет obj в вызывающий список в позицию, указанную в index . Любые ранее вставленные элементы за указанной позицией вставки смещаются вверх. То есть никакие элементы не перезаписываются. (Интерфейс List )
- Е set (int index, Е obj) — присваивает obj элементу, находящемуся в списке в позиции index . (Интерфейс List )
- boolean addAll (Collection с) — добавляет все элементы к вызывающей коллекции. Возвращает true , если операция удалась (то есть все элементы добавлены). В противном случае возвращает false . (Интерфейс Collection )
В следующем примере рассмотрим создание объекта класса ArrayList и добавление в него элементов с помощью указанных выше методов:
import java.util.ArrayList; import java.util.List; public class ArrayListAddDemo < public static void main(String[] args) < ListarrayList = new ArrayList<>(); System.out.println("Начальный размер arrayList: " + arrayList.size()); arrayList.add("C"); arrayList.add("A"); arrayList.add("E"); arrayList.add("B"); arrayList.add("D"); arrayList.add("F"); arrayList.add("F"); arrayList.add(1, "A2"); arrayList.set(0, "C2"); System.out.println("Размер arrayList после добавления: " + arrayList.size()); System.out.println("Содержимое arrayList: " + arrayList); System.out.println(arrayList.get(0)); > >
4. Методы класса ArrayList для удаления элементов
Для удобства в следующем списке приведены все методы, позволяющие удалять элементы из объекта класса ArrayList :
- boolean remove(Object obj) — удаляет один экземпляр obj из вызывающей коллекции. Возвращает true , если элемент удален. В противном случае возвращает false . (Интерфейс Collection )
- Е remove(int index) — удаляет элемент из вызывающего списка в позиции index и возвращает удаленный элемент. Результирующий список уплотняется, то есть элементы, следующие за удаленным, сдвигаются на одну позицию назад. (Интерфейс List )
- boolean removeAll(Collection с) — удаляет все элементы из вызывающей коллекции. Возвращает truе , если в результате коллекция изменяется (то есть элементы удалены). В противном случае возвращает false . (Интерфейс Collection )
- boolean retainAll(Collection с) — удаляет все элементы кроме входящих из вызывающей коллекции. Возвращает true , если в результате коллекция изменяется (то есть элементы удалены). В противном случае возвращает false . (Интерфейс Collection )
- void clear() — удаляет все элементы вызывающей коллекции. (Интерфейс Collection )
5. Пример удаления элементов из ArrayList
public class ArrayListRemoveDemo < public static void main(String[] args) < ListarrayList = new ArrayList<>(); arrayList.add("C"); arrayList.add("A"); arrayList.add("E"); arrayList.add("B"); arrayList.add("D"); arrayList.add("F"); arrayList.add("F"); arrayList.add(1, "A2"); arrayList.set(0, "C2"); System.out.println("Содержимое arrayList: " + arrayList); System.out.println("Размер arrayList после добавления: " + arrayList.size()); arrayList.remove("F"); arrayList.remove(2); System.out.println("Размер arrayList после удаления: " + arrayList.size()); System.out.println("Содержимое of arrayList: " + arrayList); > >
6. Пример использования метода removeAll() класса ArrayList
import java.util.ArrayList; import java.util.List; public class ArrayListRemoveAllDemo < public static void main(String[] args) < ListarrayList = new ArrayList<>(); arrayList.add("C"); arrayList.add("A"); arrayList.add("E"); arrayList.add("B"); arrayList.add("D"); arrayList.add("F"); arrayList.add("F"); arrayList.add(1, "A2"); arrayList.set(0, "C2"); List removeElements = List.of("C2", "A2", "AA", "F"); System.out.println("Содержимое arrayList до removeAll: " + arrayList); arrayList.removeAll(removeElements); System.out.println("Содержимое arrayList после removeAll: " + arrayList); > >
7. Пример использования методов addAll(), clear() класса ArrayList
public class ArrayListDemo2 < public static void main(String[] args) < ListarrayList1 = new ArrayList<>(); List arrayList2 = List.of("1", "2"); arrayList1.add("A"); arrayList1.add("B"); arrayList1.add("C"); arrayList1.add("D"); arrayList1.add("E"); arrayList1.add("F"); System.out.println("arrayList1 до добавления " + arrayList1); arrayList1.addAll(3, arrayList2); System.out.println("arrayList1 после добавления " + arrayList1); arrayList1.clear(); System.out.println("arrayList1 после очистки " + arrayList1); > >
8. Пример использования метода retainAll() класса ArrayList
import java.util.ArrayList; import java.util.List; public class ArrayListRetainAllDemo < public static void main(String[] args) < ListarrayList1 = new ArrayList<>(); List arrayList2 = List.of("F", "FF", "E"); arrayList1.add("A"); arrayList1.add("A"); arrayList1.add("B"); arrayList1.add("C"); arrayList1.add("D"); arrayList1.add("E"); arrayList1.add("F"); arrayList1.add("F"); arrayList1.retainAll(arrayList2); System.out.println(arrayList1); > >
9. Получение массива из ArrayList
Достаточно частая задача — это получение массива из коллекции. Для этого в интерфейсе Collection объявлен метод toArray() . Имеются два варианта метода toArray() :
-
Object [] toArray() — создает массив типа Object и записывает в него значения из вызывающей коллекции:
import java.util.Arrays; import java.util.List; public class ArrayListToStringDemo < public static void main(String[] args) < ListarrayList = List.of("C", "A", "E", "B", "D", "F"); Object[] objectArray = arrayList.toArray(); System.out.println(Arrays.toString(objectArray)); > >
import java.util.Arrays; import java.util.List; public class ArrayListToStringDemo < public static void main(String[] args) < ListarrayList = List.of("C", "A", "E", "B", "D", "F"); //1 вариант String[] stringArray1 = new String[arrayList.size()]; arrayList.toArray(stringArray1); System.out.println(Arrays.toString(stringArray1)); //2 вариант String[] stringArray2 = arrayList.toArray(new String[0]); System.out.println(Arrays.toString(stringArray2)); > >
- Интерфейс Collection
- Структуры данных
- Интерфейс Set и классы HashSet, LinkedHashSet
- Интерфейс SortedSet и класс TreeSet
- Интерфейсы Comparable и Comparator
- Интерфейс NavigableSet
- Интерфейс Queue и классы
- Интерфейс Iterator
- Интерфейс ListIterator
- Отображения Map
- Класс Collections
- Backed Collections
- Legacy Classes
- Задания
Списочный массив ArrayList
В Java массивы имеют фиксированную длину и не могут быть увеличены или уменьшены. Класс ArrayList реализует интерфейс List и может менять свой размер во время исполнения программы, при этом не обязательно указывать размерность при создании объекта. Элементы ArrayList могут быть абсолютно любых типов в том числе и null.
Пример создания объекта ArrayList
ArrayList list = new ArrayList ();
Можно инициализировать массив на этапе определения. Созданный объект list содержит свойство size. Обращение к элементам массива осуществляется с помощью метода get(). Пример :
ArrayList list; list = Arrays.asList(new String[] ); System.out.println ("Размер массива равен '" + Integer.valueOf (list.size()) + "' элементам");
Добавление элемента в массив ArrayList, метод add
Работать с ArrayList просто: необходимо создать объект и вставлять созданные объекты методом add(). Обращение к элементам массива осуществляется с помощью метода get(). Пример:
ArrayList list; list = new ArrayListЗамена элемента массива ArrayList, метод set
Чтобы заменить элемент в массиве, нужно использовать метод set() с указанием индекса и новым значением.
list.add("Яблоко"); list.add("Груша"); list.add("Слива"); list.set(1, "Персик"); System.out.println ( "2-ой элемент массива '" + list.get(1) + "'");Удаление элемента массива ArrayList, метод remove
Для удаления элемента из массива используется метод remove(). Можно удалять по индексу или по объекту:
list.remove(0); // удаляем по индексу list.remove("Слива"); // удаляем по объектуПРИМЕЧАНИЕ: элементы, следующие после удалённого элемента, перемещаются на одну позицию ближе к началу. То же самое относится и к операции вставки элемента в середину списка.
Для очистки всего массива используется метод clear():
list.clear();Определение позиции элемента ArrayList, метод indexOf
В списочном массиве ArrayList существует метод indexOf(), который ищет нужный элемент и возвращает его индекс.
int index = list.indexOf("Слива"); // выводим имя элемента и его номер в массиве System.out.println (list.get(index) + " числится под номером " + index);Отсчёт в массиве начинается с 0, если индекс равен 2, значит он является третьим в массиве.
Проверка наличие элемента в ArrayList, метод contains
Чтобы узнать, есть в массиве какой-либо элемент, можно воспользоваться методом contains(), который вернёт логическое значение true или false в зависимости от присутствия элемента в наборе :
System.out.println (list.contains("Картошка") + "");Понятно, что в массиве никаких овощей быть не может, поэтому в консоле будет отображено false.
Создание массива из элементов ArrayList, метод toArray
Для конвертирования набора элементов в обычный массив необходимо использовать метод toArray().
ArrayList myArrayList = new ArrayList(); myArrayList.add("Россия"); myArrayList.add("Польша"); myArrayList.add("Греция"); myArrayList.add("Чехия"); String[] array = <>; // конвертируем ArrayList в массив array = myArrayList.toArray(new String[myArrayList.size()]);Интерфейс List
java.util.List является интерфейсом и его следует использовать вместо ArrayList следующим образом :
List list = new ArrayList();Или укороченный вариант для Java 7:
List list = new ArrayList<>();В примере тип ArrayList заменен на List, но в объявлении оставлен new ArrayList(). Всё остальное остаётся без изменений. Это является рекомендуемым способом.
Интерфейс List реализует более общий интерфейс коллекции Collection.
Преобразование массива в список, Arrays
Для создания массива можно не только добавлять по одному объекту через метод add(), но и сразу массив с использованием Arrays.asList(. ).
Пример создания и инициализации массива из объектов Integer.
List numlist = Arrays.asList(1, 2, 5, 9, 11); System.out.println (numlist.get(2) + ""); // выводит число 5У данного способа есть недостаток. Если вы определили списочный массив таким образом, то уже не можете вставлять или удалять элемент, хотя при этом можете изменять существующий элемент.
List numlist = Arrays.asList(1, 2, 5, 9, 11); numlist.set(2, 33); // так можно numlist.add(34); // нельзя, ошибка во время исполнения System.out.println (numlist.get(2) + "");ArrayList — Java: Списки
Наиболее часто используемая коллекция в Java – это список элементов с произвольным доступом. Такой список во многом напоминает массив, но с возможностью динамического добавления элементов.
Списки в Java представлены набором классов, реализующий интерфейс List , в котором описаны общие методы для работы со списками, такими как проверка на существование, добавление, извлечение, замена и другими.
Сами классы, в первую очередь, отличаются друг от друга способом организации (структурой данных) внутри себя. Это происходит из-за того, что не существует универсально эффективного способа создать динамический список. Создатели языка Java решили предложить программистам набор разных реализаций, которые программисты должны выбирать в зависимости от того, какая реализация окажется наиболее эффективной для их ситуации. На практике такое происходит не часто и в большинстве случаев используется ArrayList , который мы и рассмотрим в этом уроке.
import java.util.ArrayList; var items = new ArrayListString>(); items.add("Sun"); // Добавляется под индексом 0 items.add("Mars"); // Добавляется под индексом 1 System.out.println(items); // => [Sun, Mars] // Проверка вхождения items.contains("Sun"); // true items.contains("sun"); // false // Извлечение по индексу items.get(0); // Sun items.get(1); // Mars items.size(); // 2В этом примере мы создали пустую коллекцию, в которую добавили два элемента с помощью метода add() , распечатали на экран и дальше провели набор типовых действий:
- contains() - проверяет наличие элемента в коллекции.
- get() - возвращает элемент по его индексу. Индексация, как и в массивах, начинается с нуля. Обращение к несуществующему индексу приводит к исключению.
- size() возвращает количество элементов.
Комбинируя эти методы, можно получить последний элемент в коллекции:
// Получение последнего элемента items.get(items.size() - 1); // Mars
В коде используется новый для нас синтаксис с угловыми скобками ArrayList . Технически это называется дженериком, но проходить мы их будем позже, так как это довольно хитрая концепция. Сейчас же просто запомните, что коллекции – это контейнеры элементов одного типа, поэтому в коллекциях всегда нужно указывать то, что будет внутри них хранится. Вот несколько примеров:
var items = new ArrayListInteger>(); items.add(100); items.add(200); System.out.println(items); // [100, 200] // Предположим что у нас есть класс User var users = new ArrayListUser>(); users.add(new User(/* параметры */));
Кроме добавления элементов, их можно изменять и удалять. Метод set() заменяет элемент списка по указанному индексу на новый:
var items = new ArrayListString>(); items.add("hexlet"); items.add("youtube"); items.set(1, "udemy"); System.out.println(items); // => [hexlet, udemy]
Метод remove() удаляет элемент списка на основе его индекса:
var items = new ArrayListString>(); items.add("hexlet"); items.add("youtube"); items.remove(0); System.out.println(items); // => [youtube]
Если у списка есть начальный набор элементов и он достаточно большой, то их можно указать сразу с помощью метода List.of() . Единственное нужно учитывать, что List.of() создает неизменяемый список, то есть его элементы можно использовать, но изменять сам список нельзя. Чтобы добавить возможность его изменения, нужно выполнить его преобразование в ArrayList .
import java.util.List; import java.util.ArrayList; // Неизменяемый список var fixedItems = List.of("Sun", "Mars", /* еще множество элементов */); var items = new ArrayList<>(fixedItems);
В таком случае Java выводит тип самостоятельно на основе типа первого параметра в List.of() . То же самое происходит и в ArrayList .
Apache Commons Collections
Стандартная библиотека предоставляет множество полезных методов для работы со списками, но даже их недостаточно для всех возникающих ситуаций. Поэтому полезно знать про библиотеку commons-collections4 , в которой содержится огромное количество полезных методов на все случаи жизни. Мы будем использовать эту библиотеку как в этом, так и в последующих курсах.
import org.apache.commons.collections4.CollectionUtils; var items = new ArrayListString>();
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях: