Привет! Collections в Java это набор статических методов для выполнения стандартных операций над коллекциями, таких как ArrayList. Он позволяет легко сортировать (sort), перемешивать (shuffle), изменять порядок (reverse), находить минимальные и максимальные элементы (min/max) и создавать неизменяемые списки (unmodifiableList). Подобно классу Arrays для массивов, Collections избавляет от необходимости писать типовые алгоритмы вручную. Давайте рассмотрим, какие именно задачи он помогает решать и как использовать его самые полезные методы.

Кратко

  • Collections (java.util.Collections) это класс со статическими методами для операций над коллекциями (например ArrayList).
  • Collections.sort() сортирует, reverse() переворачивает порядок, shuffle() перемешивает.
  • Collections.min() и max() находят наименьший и наибольший элемент.
  • Collections.unmodifiableList() создает неизменяемый список (нельзя добавлять и удалять элементы).
  • Collections.swap() меняет местами два элемента по индексам; disjoint() проверяет, есть ли у коллекций общие элементы.
  • По аналогии с классом Arrays для массивов, Collections избавляет от ручного написания типовых алгоритмов.
За последние несколько занятий мы сильно продвинулись в освоении ArrayList. Однако, в течение этого времени мы совершали только простейшие операции: удаление, вставку, вывод в консоль. Конечно, на этом список задач, с которыми сталкиваются разработчики при использовании ArrayList, не исчерпывается. Помнишь лекцию о массивах и классе Arrays? Он был разработан создателями Java специально для того, чтобы решать типовые задачи, с которыми программисты сталкиваются при работе с массивами. А что с ArrayList? Наверняка есть какой-то список типовых задач и для него. Были ли они все реализованы в каком-то отдельном классе, или нам придется каждый раз писать нужное поведение вручную? Разумеется, писать все самим не потребуется. Наиболее распространенные операции, которые совершаются при использовании коллекций в Java, уже были реализованы в специальном статическом классе Collections. Класс Collections в Java: готовые методы для операций с коллекциями

Что такое класс Collections в Java

"Коллекции" это общее название для нескольких структур данных в Java. Данные можно хранить многими разными способами. Мы пока изучили только класс ArrayList, где данные хранятся в массиве. С остальными коллекциями мы познакомимся позднее. Сейчас достаточно понимать что класс Collections рассчитан на работу не только с ArrayList, но и с другими видами коллекций в Java (отсюда, собственно, и его название). Итак, какие же задачи при работе с ArrayList позволяет решить класс Collections? Первое и самое очевидное это сортировка. В лекции о массивах мы рассматривали пример с числами, а теперь рассмотрим пример со строками. Для сортировки содержимого коллекций в классе Collections реализован метод sort():
public class Main {

   public static void main(java.lang.String[] args) {

       String mercury = new String("Меркурий");
       String venus = new String("Венера");
       String earth = new String("Земля");
       String mars = new String("Марс");
       String jupiter = new String("Юпитер");
       String saturn = new String("Сатурн");
       String uranus = new String("Уран");
       String neptune = new String("Нептун");

       ArrayList<String> solarSystem = new ArrayList<>(Arrays.asList(mercury, venus, earth, mars,
               jupiter, saturn, uranus, neptune));
       Collections.sort(solarSystem);
       System.out.println(solarSystem);

   }
}
Вывод:

[Венера, Земля, Марс, Меркурий, Нептун, Сатурн, Уран, Юпитер]
Строки были отсортированы в алфавитном порядке! Почему именно в алфавитном? В классе String запрограммировано, как именно строки сравниваются между собой (как раз по алфавиту). Для классов, которые ты будешь создавать сам, можешь реализовать свой механизм сравнения, но об этом мы поговорим в других лекциях. Кроме того, класс Collections позволяет найти минимальный и максимальный элемент в ArrayList. Это делается с помощью методов min() и max():
public static void main(java.lang.String[] args) {

   ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
   System.out.println(Collections.max(numbers));
   System.out.println(Collections.min(numbers));

}
Вывод:

7
1
Это, конечно, гораздо удобнее, чем вручную писать код для прохождения по всем элементам и поискам наибольшего или наименьшего элемента :)

Изменение порядка элементов коллекции

Еще один крайне полезный метод это reverse(). Если бы нам нужно было "перевернуть" список, чтобы элементы шли в обратном порядке, как бы мы это делали? Вероятно, написать такой алгоритм самому было бы не так просто :) К счастью, метод reverse() уже это умеет. Например, нам не нравится как метод sort() отсортировал наши планеты в алфавитном порядке, и мы хотим изменить порядок на обратный, от Я до А:
public class Main {

   public static void main(java.lang.String[] args) {

       String mercury = new String("Меркурий");
       String venus = new String("Венера");
       String earth = new String("Земля");
       String mars = new String("Марс");
       String jupiter = new String("Юпитер");
       String saturn = new String("Сатурн");
       String uranus = new String("Уран");
       String neptune = new String("Нептун");

       ArrayList<String> solarSystem = new ArrayList<>(Arrays.asList(mercury, venus, earth, mars,
               jupiter, saturn, uranus, neptune));
       Collections.sort(solarSystem);
       Collections.reverse(solarSystem);
       System.out.println(solarSystem);

   }
}
Вывод:

[Юпитер, Уран, Сатурн, Нептун, Меркурий, Марс, Земля, Венера]
Кстати, мы тут часто говорим о сортировке, порядке элементов и т.д. А что, если задача у нас будет прямо противоположная? Например, мы пытаемся реализовать механизм работы лотереи. Мы добавили в барабан 100 чисел, которые по одному должны появляться на экране. Кто из участников первым зачеркнет все числа на своем билете, тот побеждает. Реализовать такой механизм очень легко с помощью метода shuffle():
public class Main {

   public static void main(java.lang.String[] args) {

       ArrayList<Integer> lottery = new ArrayList<>(100);
       for (int i = 1; i <= 100; i++) {

           lottery.add(i);//добавляем в барабан числа от 1 до 100
       }

       Collections.shuffle(lottery);//перемешиваем
       System.out.println("Внимание! Из барабана появляются первые 10 чисел!");
       for (int i = 0; i < 10; i++) {

           System.out.println(lottery.get(i));
       }

   }
}
Вывод:

Внимание! Из барабана появляются первые 10 чисел!
32
61
4
81
25
8
66
35
42
71
Вот так просто! Задача решена, а наш кусочек игры написан :) Теперь представим другую ситуацию. Ранее мы создали список solarSystem с перечисленными в нем планетами. И он нас, вроде как, всем устраивает, если бы не одно но: из него можно удалять элементы и добавлять новые! Это явно не то поведение, которое мы ждем: Солнечная система в нашей программе должна быть в неизменном состоянии.

Неизменяемые коллекции и другие утилиты

В классе Collections есть очень интересный метод, unmodifiableList(). Он создает из переданного списка его неизменяемый вариант. В него нельзя будет ни добавить, ни удалить элемент. В случае со списком планет Солнечной системы это именно то, что нам нужно!
public class Main {

   public static void main(java.lang.String[] args) {

       String mercury = new String("Меркурий");
       String venus = new String("Венера");
       String earth = new String("Земля");
       String mars = new String("Марс");
       String jupiter = new String("Юпитер");
       String saturn = new String("Сатурн");
       String uranus = new String("Уран");
       String neptune = new String("Нептун");

       List<String> solarSystem = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(mercury, venus, earth, mars,
               jupiter, saturn, uranus, neptune)));
       solarSystem.add("Плутон");//попробуем добавить новый элемент
   }
}

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableCollection.add(Collections.java:1075)
	at Main.main(Main.java:21)
Ошибка! В solarSystem теперь нельзя ничего добавлять! Единственное, на что в данном случае нужно обратить внимание, это тип переменной: он должен быть List<>, а не ArrayList<> (данный метод возвращает объект именно такого типа, общего для всех видов списков). Еще одна рядовая ситуация, которая может произойти во время работы: программист добавил элементы в неправильном порядке. Если такое произошло, и Меркурий и Нептун неожиданно поменялись местами, исправить эту оплошность нам поможет метод swap():
public class Main {

   public static void main(java.lang.String[] args) {

       String mercury = new String("Меркурий");
       String venus = new String("Венера");
       String earth = new String("Земля");
       String mars = new String("Марс");
       String jupiter = new String("Юпитер");
       String saturn = new String("Сатурн");
       String uranus = new String("Уран");
       String neptune = new String("Нептун");

       ArrayList<String> solarSystem = new ArrayList<>(Arrays.asList(neptune, venus, earth, mars
       , jupiter, saturn, uranus, mercury));// неправильный порядок планет
       System.out.println(solarSystem);

       Collections.swap(solarSystem, solarSystem.indexOf(mercury), solarSystem.indexOf(neptune));
       System.out.println(solarSystem);

   }
}
В метод swap() мы передали наш список, а также индексы двух элементов, которые нужно поменять местами. Обрати внимание: метод работает именно с индексами, а не со ссылками. Поэтому здесь нам понадобился метод ArrayList.indexOf(). Вывод:

[Нептун, Венера, Земля, Марс, Юпитер, Сатурн, Уран, Меркурий]

[Меркурий, Венера, Земля, Марс, Юпитер, Сатурн, Уран, Нептун]
Напоследок познакомимся с очень интересным методом, disjoint(). Он проверяет, есть ли у двух коллекций пересечения, то есть хоть один одинаковый элемент. Если нет, возвращает true, если есть, false.
public class Main {

   public static void main(java.lang.String[] args) {

       String mercury = new String("Меркурий");
       String venus = new String("Венера");
       String earth = new String("Земля");
       String mars = new String("Марс");
       String jupiter = new String("Юпитер");
       String saturn = new String("Сатурн");
       String uranus = new String("Уран");
       String neptune = new String("Нептун");

       ArrayList<String> solarSystemPart1 = new ArrayList<>(Arrays.asList(mercury, venus, earth, mars));
       ArrayList<String> solarSystemPart2 = new ArrayList<>(Arrays.asList(jupiter, saturn, uranus, neptune));

       System.out.println(Collections.disjoint(solarSystemPart1, solarSystemPart2));

   }
}
Как видишь, в наших двух списках элементы полностью разные, поэтому программа выводит true.

Основные методы класса Collections

Соберем разобранные методы в одну таблицу:
МетодЧто делает
Collections.sort(list)сортирует список (строки по алфавиту, числа по возрастанию)
Collections.reverse(list)переворачивает порядок элементов
Collections.shuffle(list)перемешивает элементы случайным образом
Collections.min(list) / max(list)находит наименьший или наибольший элемент
Collections.unmodifiableList(list)создает неизменяемый список
Collections.swap(list, i, j)меняет местами элементы по индексам i и j
Collections.disjoint(a, b)true, если у коллекций нет общих элементов
Вот такой интересный и очень полезный класс. Как и Arrays, он выполняет вместо нас много рутинной, черновой работы, позволяя сосредоточиться на других вещах. Почитай о нем в документации Oracle, там есть и другие методы.

Читайте также

  • Класс ArrayList: динамический список, над которым чаще всего и работают методы Collections.
  • Класс Arrays: такой же класс-помощник, только для массивов.
  • Класс HashMap: еще одна коллекция, для хранения пар ключ-значение.

Вопросы и ответы

Что такое класс Collections в Java?

Это служебный класс java.util.Collections со статическими методами для операций над коллекциями (сортировка, перемешивание, поиск минимума и максимума и т.д.). Он работает с ArrayList и другими коллекциями.

Чем Collections отличается от Arrays?

Arrays содержит методы для работы с массивами, а Collections для работы с коллекциями (например ArrayList). Идея одна: не писать типовые алгоритмы вручную.

Как отсортировать ArrayList?

Методом Collections.sort(list). Строки сортируются по алфавиту, числа по возрастанию. Чтобы перевернуть порядок, используют Collections.reverse(list).

Как перемешать элементы коллекции?

Методом Collections.shuffle(list). Он случайным образом меняет порядок элементов, что удобно, например, для лотереи или тасования карт.

Как сделать список неизменяемым?

Методом Collections.unmodifiableList(list). В полученный список нельзя добавлять или удалять элементы; при попытке будет исключение UnsupportedOperationException. Тип переменной должен быть List, а не ArrayList.

Что делает метод disjoint()?

Он проверяет, есть ли у двух коллекций хотя бы один общий элемент. Если общих элементов нет, возвращает true, если есть, false.