← Назад к вопросам

Какая парадигма заложена в Atomic классы?

2.7 Senior🔥 181 комментариев
#JVM и управление памятью#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Что нужно соблюдать для использования For-Each

For-each (enhanced for loop) - это удобный синтаксис в Java для итерации. Но есть требования.

Главное требование: Iterable интерфейс

Объект должен реализовать интерфейс Iterable<T>:

public interface Iterable<T> {
    Iterator<T> iterator();
}

// For-each работает только с классами, которые реализуют Iterable

Использование

// ✅ Работает с Collections (все реализуют Iterable)
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");

for (String item : list) {
    System.out.println(item);
}

// ✅ Работает с Set
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);

for (Integer num : set) {
    System.out.println(num);
}

// ✅ Работает с массивами
String[] array = {"A", "B", "C"};
for (String item : array) {
    System.out.println(item);
}

// ❌ НЕ работает с Map напрямую
Map<String, Integer> map = new HashMap<>();
for (String key : map.keySet()) {  // Нужно keySet(), values() или entrySet()
    System.out.println(key);
}

Требования для собственного класса

Реализуем Iterable

public class MyCollection<T> implements Iterable<T> {
    private List<T> items = new ArrayList<>();
    
    public void add(T item) {
        items.add(item);
    }
    
    // ✅ Обязательный метод
    @Override
    public Iterator<T> iterator() {
        return items.iterator();
    }
}

// Теперь можем использовать for-each
MyCollection<String> collection = new MyCollection<>();
collection.add("A");
collection.add("B");

for (String item : collection) {
    System.out.println(item);
}

Как это работает под капотом

// For-each это синтаксический сахар
for (String item : list) {
    System.out.println(item);
}

// Компилятор превращает это в:
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
    String item = it.next();
    System.out.println(item);
}

Требования к Iterator

public interface Iterator<E> {
    boolean hasNext();  // Есть ещё элементы?
    E next();          // Получить следующий
    void remove();     // Удалить (опционально)
}

// Iterator ОБЯЗАН иметь hasNext() и next()

Пример собственного итератора

public class MyCustomIterator<T> implements Iterator<T> {
    private T[] items;
    private int index = 0;
    
    public MyCustomIterator(T[] items) {
        this.items = items;
    }
    
    @Override
    public boolean hasNext() {
        return index < items.length;
    }
    
    @Override
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        return items[index++];
    }
}

public class MyArray<T> implements Iterable<T> {
    private T[] items;
    
    public MyArray(T[] items) {
        this.items = items;
    }
    
    @Override
    public Iterator<T> iterator() {
        return new MyCustomIterator<>(items);
    }
}

// Использование
String[] array = {"A", "B", "C"};
MyArray<String> myArray = new MyArray<>(array);

for (String item : myArray) {
    System.out.println(item);
}

Ограничения for-each

❌ Нельзя удалять элементы

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");

// ❌ Ошибка! ConcurrentModificationException
for (String item : list) {
    if (item.equals("B")) {
        list.remove(item);  // Модификация во время итерации
    }
}

// ✅ Правильно - используем Iterator
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
    String item = it.next();
    if (item.equals("B")) {
        it.remove();  // Безопасное удаление
    }
}

❌ Нельзя изменять index

// ❌ Нельзя так
for (String item : list) {
    // Нет доступа к индексу
    // System.out.println(i);  // i не существует
}

// ✅ Если нужен индекс
for (int i = 0; i < list.size(); i++) {
    System.out.println(i + ": " + list.get(i));
}

❌ Нельзя использовать на null

List<String> list = null;

// ❌ NullPointerException
for (String item : list) {
    System.out.println(item);
}

// ✅ Проверяем перед итерацией
if (list != null) {
    for (String item : list) {
        System.out.println(item);
    }
}

Что реализует Iterable

✅ List (ArrayList, LinkedList, etc)
✅ Set (HashSet, TreeSet, etc)
✅ Queue (LinkedList, PriorityQueue, etc)
✅ Deque (LinkedList, ArrayDeque, etc)
✅ Массивы примитивов и объектов
❌ Map (нужно keySet(), values(), entrySet())

Итерация Map

Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);

// Правильные способы итерации

// 1. По ключам
for (String key : map.keySet()) {
    System.out.println(key);
}

// 2. По значениям
for (Integer value : map.values()) {
    System.out.println(value);
}

// 3. По парам ключ-значение (лучше всего)
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

Резюме требований для for-each

  1. Реализовать Iterable<T> интерфейс
  2. Реализовать iterator() метод
  3. Iterator должен иметь hasNext() и next()
  4. Не удалять элементы во время итерации (используй it.remove())
  5. Не изменять коллекцию во время итерации
  6. Не null
  7. Для Map используй keySet(), values() или entrySet()