The Stream class introduces many new functions that combine the stream and return a single value such as average
, sum
, min
, max
, and count
etc and some user-defined functions as well. These operations are called reduction functions.
these functions are terminal operations. It aggregates or combines the Numeric streams into either some predefined reductions and can take user-defined functions as well.
package org.wesome.java8;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.stream.IntStream;
class Apple {
public static void main(String args[]) {
List<String> apples = Arrays.asList("Macintosh", "Fuji", "Gala", "Jonagold");
apples.stream().reduce((left, right) -> left.concat(" # ").concat(right)).ifPresent(System.out::println);
System.out.println("-------------------sum---------------------");
int sum = IntStream.rangeClosed(1, 5).sum();
System.out.println("sum = " + sum);
System.out.println("-------------------average---------------------");
OptionalDouble average = IntStream.rangeClosed(1, 5).average();
System.out.println("average = " + average.getAsDouble());
System.out.println("-------------------min---------------------");
OptionalInt min = IntStream.rangeClosed(1, 5).min();
System.out.println("min = " + min.getAsInt());
System.out.println("-------------------max---------------------");
OptionalInt max = IntStream.rangeClosed(1, 5).max();
System.out.println("max = " + max.getAsInt());
System.out.println("-------------------count---------------------");
long count = IntStream.rangeClosed(1, 5).count();
System.out.println("count = " + count);
}
}
Reduce
function can be called in multiple ways such as lambda
function, method reference and customer methods as well. The over loaded reduce
function doesn't take a default value hence it returns the optional
type because the stream can be empty as well.
package org.wesome.java8;
import java.util.OptionalInt;
import java.util.stream.IntStream;
class Apple {
public static int add(int number1, int number2) {
return number1 + number2;
}
public static void main(String args[]) {
System.out.println("-------------------reduce with lambda---------------------");
OptionalInt sumWithLambda = IntStream.rangeClosed(1, 5).reduce((x, y) -> x + y);
System.out.println("sumWithLambda = " + sumWithLambda.getAsInt());
System.out.println("-------------------reduce with Custom Method Reference---------------------");
OptionalInt sumWithMethodReference = IntStream.rangeClosed(1, 5).reduce(Apple::add);
System.out.println("sumWithMethodReference = " + sumWithMethodReference.getAsInt());
System.out.println("-------------------sum With Method Reference---------------------");
OptionalInt sumWithIdentity = IntStream.rangeClosed(1, 5).reduce(Integer::sum);
System.out.println("sumWithIdentity = " + sumWithIdentity.getAsInt());
}
}
reduce
takes identity
which is the initial
value as well as the default
value of the function if there is no value in the stream and a BinaryOperator
as an accumulator
. Since the overloaded reduce
function takes identity
as a default
value, hence it returns numeric primitive types.
package org.wesome.java8;
import java.util.stream.IntStream;
class Apple {
public static int add(int number1, int number2) {
return number1 + number2;
}
public static void main(String args[]) {
System.out.println("-------------------sum With Identity---------------------");
int sumWithIdentit = IntStream.rangeClosed(1, 5).reduce(100, Integer::sum);
System.out.println("sumWithIdentit = " + sumWithIdentit);
System.out.println("-------------------Identity as default value---------------------");
int sum = IntStream.empty().reduce(100, Integer::sum);
System.out.println("sum = " + sum);
}
}
Find min
in User-defined
class using Reduce
function.
package org.wesome.java8;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Data
@AllArgsConstructor
class Fruit {
int fruitId;
String fruitName;
int price;
public static void main(String[] args) {
List<Fruit> apples = new ArrayList<>();
apples.add(new Fruit(1, "Macintosh", 3));
apples.add(new Fruit(2, "Fuji", 1));
apples.add(new Fruit(3, "Gala", 4));
apples.add(new Fruit(4, "Jonagold", 2));
Optional<Fruit> apple = apples.stream().reduce((apple1, apple2) -> apple1.getPrice() > apple2.getPrice() ? apple1 : apple2);
apple.ifPresent(System.out::println);
}
}