Java - Stream Map Reduce Operation

Introduction

The following method from Stream can perform a map operation, followed by a reduce operation.

<U> U reduce(U identity, 
             BiFunction<U,? super T,U> accumulator, 
             BinaryOperator<U> combiner)

The second argument is the accumulator, takes an argument whose type may be different from the type of the stream.

The third argument combines the partial results when the reduce operation is performed in parallel.

The following code prints the sum of the incomes of all people:

double sum = Person.persons()
        .stream()
        .reduce(0.0, (partialSum, person) -> partialSum + person.getIncome(), Double::sum);
System.out.println(sum);

The third parameter is used in parallel Stream.

Demo

import java.time.LocalDate;
import java.time.Month;
import java.util.Arrays;
import java.util.List;

public class Main {
  public static void main(String[] args) {
    double sum = Person.persons()//
        .stream()//
        .reduce(0.0, //
            (Double partialSum, Person p) -> {//
              double accumulated = partialSum + p.getIncome();//
              System.out.println(Thread.currentThread().getName() + //
              " - Accumulator: partialSum = " + //
              partialSum + ", person = " + p + //
              ", accumulated = " + accumulated);//
              return accumulated;//
            }, //
            (a, b) -> {//
              double combined = a + b;//
              System.out.println(Thread.currentThread().getName() + //
              " - Combiner: a = " + a + ", b = " + b + //
              ", combined = " + combined);//
              return combined;//
            });//

    System.out.println(sum);/*from w  w w .  jav  a 2 s. c  om*/

    sum = Person.persons()//
        .parallelStream()//
        .reduce(0.0, //
            (Double partialSum, Person p) -> {//
              double accumulated = partialSum + p.getIncome();//
              System.out.println(Thread.currentThread().getName() + //
              " - Accumulator: partialSum = " + //
              partialSum + ", person = " + p + //
              ", accumulated = " + accumulated);//
              return accumulated;//
            }, //
            (a, b) -> {//
              double combined = a + b;//
              System.out.println(Thread.currentThread().getName() + //
              " - Combiner: a = " + a + ", b = " + b + //
              ", combined = " + combined);//
              return combined;//
            });//

    System.out.println(sum);
  }
}

class Person {
  // An enum to represent the gender of a person
  public static enum Gender {
    MALE, FEMALE
  }

  private long id;
  private String name;
  private Gender gender;
  private LocalDate dob;
  private double income;

  public Person(long id, String name, Gender gender, LocalDate dob, double income) {
    this.id = id;
    this.name = name;
    this.gender = gender;
    this.dob = dob;
    this.income = income;
  }

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Gender getGender() {
    return gender;
  }

  public boolean isMale() {
    return this.gender == Gender.MALE;
  }

  public boolean isFemale() {
    return this.gender == Gender.FEMALE;
  }

  public void setGender(Gender gender) {
    this.gender = gender;
  }

  public LocalDate getDob() {
    return dob;
  }

  public void setDob(LocalDate dob) {
    this.dob = dob;
  }

  public double getIncome() {
    return income;
  }

  public void setIncome(double income) {
    this.income = income;
  }

  public static List<Person> persons() {
    Person ken = new Person(1, "Java", Gender.MALE, LocalDate.of(1970, Month.MAY, 4), 6020.0);
    Person jeff = new Person(2, "Jack", Gender.MALE, LocalDate.of(1970, Month.JULY, 15), 7320.0);
    Person donna = new Person(3, "Javascript", Gender.FEMALE, LocalDate.of(1972, Month.JULY, 29), 8720.0);
    Person chris = new Person(4, "XML", Gender.MALE, LocalDate.of(1993, Month.DECEMBER, 16), 5800.0);
    Person laynie = new Person(5, "Json", Gender.FEMALE, LocalDate.of(2002, Month.DECEMBER, 13), 0.0);
    Person lee = new Person(6, "Database", Gender.MALE, LocalDate.of(2011, Month.MAY, 9), 2400.0);

    // Create a list of persons
    List<Person> persons = Arrays.asList(ken, jeff, donna, chris, laynie, lee);

    return persons;
  }

  @Override
  public String toString() {
    String str = String.format("(%s, %s, %s, %s, %.2f)", id, name, gender, dob, income);
    return str;
  }
}

Result

Related Topics