1. Перетворення елементів колекцій
У програмуванні одна з найчастіших операцій — перетворення колекції: у нас є колекція даних одного типу, і на її основі потрібно створити нову колекцію іншого типу. Наприклад, зі списку обʼєктів типу User отримати список їхніх імен (String) або зі списку чисел — список їхніх квадратів.
Найпростіший і найзрозуміліший спосіб у Java — використовувати імперативний підхід, тобто звичайний цикл for (часто — for-each).
Приклад: зі списку рядків отримати список їхніх довжин
Припустімо, у нас є список назв міст:
List<String> cities = List.of("Лондон", "Париж", "Токіо", "Нью-Йорк");
Наше завдання — створити новий список, який міститиме довжину кожної назви. Підсумковий результат має бути: [6, 5, 5, 8].
Рішення за допомогою циклу for:
import java.util.ArrayList;
import java.util.List;
public class CollectionTransform {
public static void main(String[] args) {
List<String> cities = List.of("Лондон", "Париж", "Токіо", "Нью-Йорк");
List<Integer> lengths = new ArrayList<>(); // Створюємо новий порожній список для результату
for (String city : cities) {
// Для кожного елемента списку cities обчислюємо його довжину...
int length = city.length();
// ...і додаємо цей результат до нового списку
lengths.add(length);
}
System.out.println(lengths); // Виведе: [6, 5, 5, 8]
}
}
Починаємо зі створення нової порожньої колекції для результатів — перетворення не змінює початкову колекцію. Для обходу початкової колекції використовуємо цикл for-each і всередині застосовуємо потрібну логіку (length()) до кожного елемента, а результат додаємо до нового списку через add.
2. Перетворення обʼєктів
Часто ми працюємо зі складнішими типами даних. Припустімо, у нас є клас Product, і потрібно отримати список його назв (або цін).
public class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
Тепер, маючи список продуктів, отримаємо список їхніх назв:
import java.util.ArrayList;
import java.util.List;
public class ProductExample {
public static void main(String[] args) {
List<Product> products = List.of(
new Product("Ноутбук", 1200.0),
new Product("Миша", 25.5),
new Product("Клавіатура", 75.0)
);
// Створюємо новий список для назв
List<String> productNames = new ArrayList<>();
for (Product product : products) {
// Для кожного обʼєкта Product отримуємо його назву
productNames.add(product.getName());
}
System.out.println(productNames); // Виведе: [Ноутбук, Миша, Клавіатура]
}
}
Логіка та сама: ітеруємося елементами початкової колекції, застосовуємо до кожного елемента потрібний метод (наприклад, getName()) і додаємо результат до нової колекції.
3. Робота з вкладеними колекціями
Розглянемо випадок зі списком списків: кілька відділів, у кожному — свій список працівників. Завдання — отримати один загальний («плоский») список усіх працівників.
Приклад: обʼєднання списків працівників
List<List<String>> departments = List.of(
List.of("Ганна", "Борис"),
List.of("Вікторія", "Гліб", "Дмитро"),
List.of("Олена")
);
Хочемо отримати єдиний список: [Ганна, Борис, Вікторія, Гліб, Дмитро, Олена].
Спосіб 1: за допомогою методу addAll()
import java.util.ArrayList;
import java.util.List;
public class NestedCollectionExample {
public static void main(String[] args) {
List<List<String>> departments = List.of(
List.of("Ганна", "Борис"),
List.of("Вікторія", "Гліб", "Дмитро"),
List.of("Олена")
);
List<String> allEmployees = new ArrayList<>();
// Перебираємо кожен список (відділ)
for (List<String> department : departments) {
// Додаємо всі елементи з поточного списку до спільного списку
allEmployees.addAll(department);
}
System.out.println(allEmployees); // [Ганна, Борис, Вікторія, Гліб, Дмитро, Олена]
}
}
Спосіб 2: вкладений цикл — те саме, але «вручну»:
List<List<String>> departments = List.of(...);
List<String> allEmployees = new ArrayList<>();
for (List<String> department : departments) { // Зовнішній цикл за відділами
for (String employee : department) { // Внутрішній цикл за працівниками
allEmployees.add(employee);
}
}
System.out.println(allEmployees);
Обидва способи еквівалентні за результатом. Метод addAll() по суті інкапсулює логіку вкладеного циклу й робить код коротшим.
4. Складні випадки та перетворення з умовами
Іноді перетворення потрібно виконувати лише для елементів, які відповідають умові. Наприклад, отримати список назв міст, які починаються з літери «Н», і взяти їхні довжини. Тут ми поєднуємо фільтрацію та перетворення: if + виклик методу (length()).
import java.util.ArrayList;
import java.util.List;
public class ConditionalTransform {
public static void main(String[] args) {
List<String> cities = List.of("Лондон", "Париж", "Токіо", "Нью-Йорк", "Нюрнберг");
List<Integer> lengths = new ArrayList<>();
for (String city : cities) {
// Спочатку перевіряємо умову
if (city.startsWith("Н")) {
// Якщо умову виконано, застосовуємо перетворення
lengths.add(city.length());
}
}
System.out.println(lengths); // Виведе: [8, 8]
}
}
Шаблон такий: усередині циклу спершу фільтруємо елемент за умовою (startsWith, порівняння, перевірка діапазону тощо), потім застосовуємо потрібне перетворення й додаємо результат до нового списку.
5. Типові помилки та підводні камені
Помилка № 1: зміна початкової колекції під час обходу. Поширена помилка — спроба додавати/видаляти елементи з початкової колекції безпосередньо в циклі for-each. Це призводить до помилок і непередбачуваної поведінки. Рішення: завжди створюйте новий список для результатів і наповнюйте його.
Помилка № 2: некоректне приведення типів. Якщо ви працюєте з «сирими» колекціями (наприклад, через Object) і виконуєте перетворення елементів до неправильного типу, отримаєте ClassCastException. Використовуйте узагальнення (List<T>) і стежте за сигнатурами.
Помилка № 3: неефективне використання ресурсів. Для дуже великих колекцій постійне створення нових списків і копіювання елементів можуть бути відчутними за витратами памʼяті й часу. У більшості повсякденних завдань це прийнятно, але під час обробки великих обсягів даних враховуйте складність і, за потреби, оптимізуйте підхід.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ