Java › Functional Interfaces & Method References
How would you use BiFunction combined with Stream's reduce() to implement a custom aggregation, and how does this relate to the more general concept of a fold operation in functional programming?
AdvancedAnswer
Stream.reduce() combines stream elements into a single result using a BinaryOperator<T> (a specialized BiFunction<T,T,T>) that takes an accumulated result so far and the next element, returning a new accumulated result -- this is a direct implementation of the classic functional programming 'fold' concept (also called reduce in many other languages), where reduce(identity, accumulator) processes elements left-to-right, starting from the identity value and repeatedly applying the accumulator function, letting you express custom aggregations (sum, concatenation, finding a maximum by custom criteria) declaratively rather than with an explicit mutable-accumulator loop.
List<String> words = List.of("Hello", "World", "Java");
String concatenated = words.stream()
.reduce("", (acc, word) -> acc.isEmpty() ? word : acc + " " + word);
System.out.println(concatenated); // "Hello World Java"
// Equivalent explicit imperative loop, which reduce() replaces declaratively:
// String result = "";
// for (String word : words) { result = result.isEmpty() ? word : result + " " + word; }Real-world example A financial report aggregating a stream of transaction amounts into a running total with custom rounding logic applied at each step uses Stream.reduce() with a custom BinaryOperator<BigDecimal>, expressing the entire aggregation declaratively rather than as an explicit mutable-accumulator for-loop.