1. Пошук елементів у колекціях
Пошук за допомогою стандартних методів
Коли у вас є список, наприклад, імен:
List<String> names = List.of("Анна", "Борис", "Вікторія", "Анна", "Дмитро");
Java пропонує кілька зручних методів для пошуку:
- contains(Object o) — перевіряє, чи міститься елемент у колекції.
- indexOf(Object o) — повертає перший індекс входження елемента (або -1, якщо не знайдено).
- lastIndexOf(Object o) — повертає останній індекс входження елемента (або -1).
Приклади:
System.out.println(names.contains("Анна")); // true
System.out.println(names.indexOf("Анна")); // 0
System.out.println(names.lastIndexOf("Анна")); // 3
System.out.println(names.contains("Сергій")); // false
Факт: У колекціях типу Set методів indexOf і lastIndexOf немає — Set не має індексів — у ньому лише унікальні значення.
Пошук за умовою
Іноді потрібно знайти не конкретне значення, а елемент, що відповідає умові. Наприклад, знайти перше імʼя довше ніж 6 символів. Звичайний цикл for підходить чудово: щойно знайшли відповідний елемент, скористайтеся break.
List<String> names = List.of("Анна", "Борис", "Вікторія", "Анна", "Дмитро");
String found = null;
for (String name : names) {
if (name.length() > 6) {
found = name;
break; // Знайшли перший відповідний, можна вийти з циклу
}
}
System.out.println(found); // Вікторія
Пошук максимального та мінімального значень
Для колекцій із порівнюваними елементами (наприклад, числами) можна швидко знайти максимум і мінімум за допомогою класу Collections.
List<Integer> numbers = List.of(10, 5, 20, 7, 20, 3);
int max = Collections.max(numbers); // 20
int min = Collections.min(numbers); // 3
System.out.println("Максимум: " + max);
System.out.println("Мінімум: " + min);
Важливо: Елементи мають бути порівнюваними (реалізовувати Comparable), інакше потрібно передати компаратор.
2. Сортування колекцій
Сортування списку за замовчуванням
Сортувати можна лише змінні списки (наприклад, ArrayList, LinkedList). Колекції типу Set і Map не підтримують сортування безпосередньо.
За замовчуванням сортування відбувається за «природним порядком»: для чисел — зростання, для рядків — за алфавітом.
List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
Collections.sort(numbers);
System.out.println(numbers); // [1, 3, 5, 7]
Те саме можна зробити через метод списку sort:
List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
numbers.sort(null); // null означає: використовувати природний порядок
System.out.println(numbers); // [1, 3, 5, 7]
Сортування з компаратором
Якщо потрібне власне правило сортування — наприклад, сортувати рядки за довжиною:
List<String> words = new ArrayList<>(List.of("кіт", "слон", "муха", "носоріг"));
words.sort(Comparator.comparingInt(String::length));
System.out.println(words); // [кіт, муха, слон, носоріг]
У зворотному порядку:
words.sort(Comparator.comparingInt(String::length).reversed());
System.out.println(words); // [носоріг, муха, слон, кіт]
Старий підхід через Collections.sort:
Collections.sort(words, Comparator.comparingInt(String::length));
3. Особливості сортування різних колекцій
Сортування змінює лише список
Методи сортування (sort, Collections.sort) працюють лише з колекціями, які підтримують порядок елементів (наприклад, List). Для Set і Map такі методи не передбачені.
Спроба відсортувати Set:
Set<Integer> mySet = new HashSet<>(List.of(3, 1, 2));
Collections.sort(mySet); // Помилка компіляції: метод sort очікує List!
Якщо потрібно отримати відсортований список із Set:
List<Integer> sortedFromSet = new ArrayList<>(mySet);
Collections.sort(sortedFromSet);
System.out.println(sortedFromSet); // [1, 2, 3]
Сортування Map: за ключами й за значеннями
Сортувати Map безпосередньо не можна, але можна:
- Отримати список пар «ключ — значення»
- Відсортувати його потрібним чином
- За потреби зібрати новий Map
Приклад: сортування за значеннями
Map<String, Integer> scores = Map.of(
"Анна", 15,
"Борис", 20,
"Віка", 12
);
List<Map.Entry<String, Integer>> entries = new ArrayList<>(scores.entrySet());
entries.sort(Map.Entry.comparingByValue());
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Віка: 12
// Анна: 15
// Борис: 20
Сортування обʼєктів за полем
Припустімо, у вас є клас користувача:
class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
І список користувачів:
List<User> users = new ArrayList<>(List.of(
new User("Анна", 22),
new User("Борис", 18),
new User("Віка", 25)
));
Сортуємо за віком:
users.sort(Comparator.comparingInt(u -> u.age));
System.out.println(users); // [Борис (18), Анна (22), Віка (25)]
У зворотному порядку:
users.sort(Comparator.comparingInt((User u) -> u.age).reversed());
System.out.println(users); // [Віка (25), Анна (22), Борис (18)]
4. Типові помилки під час пошуку та сортування колекцій
Помилка № 1: Сортування незмінного списку. Списки, створені через List.of(...), змінювати не можна — під час виклику sort буде викинуто UnsupportedOperationException.
List<Integer> immutable = List.of(3, 1, 2);
immutable.sort(null); // Викине виняток!
Помилка № 2: Сортування Set або Map безпосередньо. Методи сортування не працюють із Set і Map. Якщо потрібно відсортувати, спочатку перетворіть дані на список.
Помилка № 3: Неправильне порівняння обʼєктів. Не віднімайте цілі числа безпосередньо під час порівняння — можливі переповнення. Замість u1.age - u2.age використовуйте Integer.compare або Comparator.comparingInt.
// users.sort((u1, u2) -> u1.age - u2.age); // Працює, але небезпечно через ризик переповнення!
Помилка № 4: Використання contains для складного пошуку. Метод contains перевіряє лише повний збіг (за equals). Якщо потрібно шукати за частиною рядка або за полем обʼєкта — використовуйте цикл із перевіркою умови або компаратори чи стріми.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ