В каких случаях и чем можно заменить Stream API в Java?

«В каких случаях и чем можно заменить Stream API в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Stream API заменяют обычными циклами или итераторами в случаях, когда критична производительность или требуется простая отладка.

1. Замена на цикл for-each (для фильтрации, преобразования):

// Stream API
List<String> filtered = list.stream()
                            .filter(s -> s.startsWith("A"))
                            .collect(Collectors.toList());

// Цикл for-each
List<String> filtered = new ArrayList<>();
for (String s : list) {
    if (s.startsWith("A")) {
        filtered.add(s);
    }
}

Почему цикл может быть лучше: Меньшие накладные расходы, нет создания стрима и коллекторов, проще отладка пошаговым выполнением.

2. Замена на обычный цикл for с индексом (когда нужен индекс или изменение коллекции):

for (int i = 0; i < array.length; i++) {
    if (array[i] == null) {
        array[i] = defaultValue;
    }
}

3. Ручная агрегация через Iterator:

Iterator<Item> it = collection.iterator();
while (it.hasNext()) {
    Item current = it.next();
    if (shouldRemove(current)) {
        it.remove(); // Безопасное удаление во время итерации
    }
}

Когда Stream API предпочтительнее: Для написания читаемого, декларативного кода при цепочных операциях (map, filter, reduce) над данными, где производительность не является узким местом.