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

Возвращает ли reduce объект

1.0 Junior🔥 131 комментариев
#Stream API и функциональное программирование#Основы Java

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

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

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

# Возвращает ли reduce объект?

Да, метод reduce() в Java Streams может возвращать объект. Это один из самых гибких методов терминальных операций, который позволяет аккумулировать результат в любой тип данных.

Основной синтаксис reduce

// Форма 1: Optional<T> reduce(BinaryOperator<T> accumulator)
Optional<Integer> sum = Stream.of(1, 2, 3)
    .reduce((a, b) -> a + b);
// Возвращает Optional, потому что поток может быть пустым

// Форма 2: T reduce(T identity, BinaryOperator<T> accumulator)
Integer sum = Stream.of(1, 2, 3)
    .reduce(0, (a, b) -> a + b);
// Возвращает значение типа T (в данном случае Integer)

// Форма 3: <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
String result = Stream.of("a", "b", "c")
    .reduce("", String::concat, String::concat);
// Возвращает объект типа U (в данном случае String)

Возврат простых типов

// Возврат Integer
Integer sum = Stream.of(1, 2, 3, 4, 5)
    .reduce(0, Integer::sum);
// Результат: 15

// Возврат Double
Double average = Stream.of(1.0, 2.0, 3.0)
    .reduce(0.0, Double::sum);
// Результат: 6.0

// Возврат Boolean
Boolean allPositive = Stream.of(1, 2, 3)
    .reduce(true, (acc, val) -> acc && val > 0, (a, b) -> a && b);

Возврат сложных объектов

// Класс для накопления результата
public class Summary {
    public int sum;
    public int count;
    public double average;
    
    public Summary(int sum, int count) {
        this.sum = sum;
        this.count = count;
        this.average = count > 0 ? (double) sum / count : 0;
    }
}

// reduce возвращает объект Summary
Summary stats = Stream.of(1, 2, 3, 4, 5)
    .reduce(
        new Summary(0, 0),
        (summary, value) -> {
            summary.sum += value;
            summary.count++;
            summary.average = (double) summary.sum / summary.count;
            return summary;
        },
        (s1, s2) -> {
            Summary combined = new Summary(s1.sum + s2.sum, s1.count + s2.count);
            return combined;
        }
    );

System.out.println("Sum: " + stats.sum);      // 15
System.out.println("Count: " + stats.count);  // 5
System.out.println("Average: " + stats.average); // 3.0

Возврат Collections

// Накопление в List
List<String> list = Stream.of("a", "b", "c")
    .reduce(
        new ArrayList<>(),
        (acc, val) -> {
            acc.add(val);
            return acc;
        },
        (list1, list2) -> {
            list1.addAll(list2);
            return list1;
        }
    );
// Результат: [a, b, c]

// Накопление в Map
Map<String, Integer> wordCount = Stream.of("apple", "apple", "banana", "cherry", "banana")
    .reduce(
        new HashMap<>(),
        (map, word) -> {
            map.put(word, map.getOrDefault(word, 0) + 1);
            return map;
        },
        (map1, map2) -> {
            map2.forEach((key, value) -> map1.merge(key, value, Integer::sum));
            return map1;
        }
    );
// Результат: {apple=2, banana=2, cherry=1}

// Накопление в Set
Set<Integer> uniqueNumbers = Stream.of(1, 2, 2, 3, 3, 3)
    .reduce(
        new HashSet<>(),
        (set, num) -> {
            set.add(num);
            return set;
        },
        (set1, set2) -> {
            set1.addAll(set2);
            return set1;
        }
    );
// Результат: {1, 2, 3}

Практический пример: Агрегирование объектов

public class Person {
    public String name;
    public int age;
    public double salary;
    
    public Person(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
}

public class Statistics {
    public double totalSalary;
    public int count;
    
    public Statistics(double totalSalary, int count) {
        this.totalSalary = totalSalary;
        this.count = count;
    }
    
    public double getAverageSalary() {
        return count > 0 ? totalSalary / count : 0;
    }
}

// Использование reduce для вычисления статистики
Statistics stats = Stream.of(
    new Person("Alice", 30, 50000),
    new Person("Bob", 25, 45000),
    new Person("Charlie", 35, 60000)
)
.reduce(
    new Statistics(0, 0),
    (stat, person) -> new Statistics(
        stat.totalSalary + person.salary,
        stat.count + 1
    ),
    (s1, s2) -> new Statistics(
        s1.totalSalary + s2.totalSalary,
        s1.count + s2.count
    )
);

System.out.println("Average salary: " + stats.getAverageSalary()); // 51666.66

Сравнение с collect()

Для накопления в коллекции часто лучше использовать collect() вместо reduce():

// collect() — предпочтительный способ
List<String> list = Stream.of("a", "b", "c")
    .collect(Collectors.toList());

// reduce() — более сложный вариант
List<String> list = Stream.of("a", "b", "c")
    .reduce(
        new ArrayList<>(),
        (acc, val) -> { acc.add(val); return acc; },
        (l1, l2) -> { l1.addAll(l2); return l1; }
    );

Ответ на вопрос

ДА, reduce() возвращает объект. Точнее:

  1. Optional<T> — когда используется форма без identity
  2. T — когда указана identity, результат того же типа
  3. U — любой тип данных (простой тип, объект, коллекция)

Это делает reduce() одним из самых универсальных методов Stream API для трансформации и агрегирования данных.

Возвращает ли reduce объект | PrepBro