基於list stream: reduce的使用實例

list stream: reduce的使用

stream 中的 reduce 的主要作用就是stream中元素進行組合,組合的方式可以是加減乘除,也可以是拼接等,接下來我們就通過實例來看一下reduce的用法:

reduce 一共有三種實現

1、第一種

T reduce(T identity, BinaryOperator accumulator);

該實現有起始值 identity, 起始值的類型決定瞭返回結果的類型,通過 accumulator 操作最終得到 identity 類型的返回結果

2、第二種

Optional<T> reduce(BinaryOperator accumulator);

該實現隻有一個參數 accumulator , 由於沒有辦法確定具體的返回結果,所以該方法返回的是 Optional

3、第三種

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

該方法有三個參數 identity 、 accumulator 、combiner ,該方法通過 identity 和 accumulator的處理得出最終結果,結果和第一個參數的類型相同

首先把我們下面操作的這個實體對象先放在這裡

pulbic class User {
  //ID
  private Long id;
  //年齡
  private int age;
  //班級
  private String classes;
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  public String getClasses() {
    return classes;
  }
  public void setClasses(String classes) {
    this.classes = classes;
  }
  @Override
  public String toString() {
    return "User{" +
      "id=" + id +
      ", age=" + age +
      ", classes='" + classes + '\'' +
      '}';
  }

用來求和,如下所示是四種不同的方式來獲取User對象中的age隻和,其中兩種是通過reduce來進行求和

List<User> userList = new ArrayList<>();
    User user1 = new User();
    user1.setAge(10);
    userList.add(user1);
    User user2 = new User();
    user2.setAge(20);
    userList.add(user2);
    User user3 = new User();
    user3.setAge(25);
    userList.add(user3);
    int ageSumThree = userList.stream().map(User::getAge).reduce(0, Integer::sum);
    System.out.println("ageSumThree: "  + ageSumThree);
    int ageSumFive = userList.stream().map(User::getAge).reduce(Integer::sum).orElse(0);
    System.out.println("ageSumFive: "  + ageSumFive);
    int ageSumOne = userList.stream().collect(Collectors.summingInt(User::getAge));
    System.out.println("ageSumOne" + ageSumOne);
    int ageSumFour = userList.stream().mapToInt(User::getAge).sum();
    System.out.println("ageSumFour: "  + ageSumFour);

用來求最大最小值,如下所示是求User中age的最大最小值

public static void main(String[] args) {
List<User> userList = new ArrayList<>();
    User user1 = new User();
    user1.setAge(10);
    userList.add(user1);
    User user2 = new User();
    user2.setAge(20);
    userList.add(user2);
    User user3 = new User();
    user3.setAge(25);
    userList.add(user3);
    User user4 = new User();
    user4.setAge(25);
    userList.add(user4);
    int min = userList.stream().map(User::getAge).reduce(Integer::min).orElse(0);
    System.out.println("min : " + min);
    int max = userList.stream().map(User::getAge).reduce(Integer::max).orElse(0);
    System.out.println("max : " + max);
}

用來拼接字符串,如下所示:

public static void main(String[] args) {
List<User> userList = new ArrayList<>();
    User user1 = new User();
    user1.setAge(10);
    userList.add(user1);
    User user2 = new User();
    user2.setAge(20);
    userList.add(user2);
    User user3 = new User();
    user3.setAge(25);
    userList.add(user3);
    User user4 = new User();
    user4.setAge(25);
    userList.add(user4);
    String append = userList.stream().map(User::toString).reduce("拼接字符串:", String::concat);
    System.out.println("append : " + append);
}

計算平均值:計算User對象中age字段的平均值

public static void main(String[] args) {
List<User> userList = new ArrayList<>();
    User user1 = new User();
    user1.setAge(10);
    userList.add(user1);
    User user2 = new User();
    user2.setAge(20);
    userList.add(user2);
    User user3 = new User();
    user3.setAge(25);
    userList.add(user3);
    User user4 = new User();
    user4.setAge(25);
    userList.add(user4);
    double average = userList.stream().mapToInt(User::getAge).average().orElse(0.0);
    System.out.println("average : " + average);
}

reduce的基本用法

1、初識 reduce 的基本 api

    @Test
    public void testReduce() {
        Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
        //求集合元素隻和
        Integer result = stream.reduce(0, Integer::sum);
        System.out.println(result);
        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求和
        stream.reduce((i, j) -> i + j).ifPresent(System.out::println);
        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求最大值
        stream.reduce(Integer::max).ifPresent(System.out::println);
        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求最小值
        stream.reduce(Integer::min).ifPresent(System.out::println);
        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //做邏輯
        stream.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);
        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求邏輯求乘機
        int result2 = stream.filter(i -> i % 2 == 0).reduce(1, (i, j) -> i * j);
        Optional.of(result2).ifPresent(System.out::println);
    }

2、應用場景測試

求所有學生的成績之和。

package com.jd;
import com.jd.bean.Score;
import com.jd.bean.Student;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
/**
 * @author: wangyingjie1
 * @version: 1.0
 * @createdate: 2017-09-26 09:35
 */
public class ReduceTest {
    @Test
    public void reduceList() {
        List<Student> list = getStudents();
        //使用Reduce 將所有的所有的成績進行加和
        Optional<Score> totalScore = list.stream()
                .map(Student::getScore)
                .reduce((x, y) -> x.add(y));
        System.out.println(totalScore.get().getPoint());
    }
    @Test
    public void reduceList2() {
        List<Student> list = getStudents();
        Student student = getStudent();
        //使用Reduce 求 list 、student 的總成績之和
        Score scoreSum = list.stream()
                .map(Student::getScore)
                //相當於加瞭一個初始值
                .reduce(student.getScore(), (x, y) -> x.add(y));
        System.out.println(scoreSum.getPoint());
    }
    private Student getStudent() {
        Student student = new Student();
        student.setId(4);
        Score score = new Score();
        score.setPoint(100);
        student.setScore(score);
        return student;
    }
    private List<Student> getStudents() {
        List<Student> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Student stu = new Student();
            Score score = new Score();
            score.setPoint(80);
            score.setCourseName("English");
            stu.setId(i);
            stu.setScore(score);
            list.add(stu);
        }
        return list;
    }
}
package com.jd.bean;
//學生
public class Student {
    private Integer id;
    //課程分數
    private Score score;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Score getScore() {
        return score;
    }
    public void setScore(Score score) {
        this.score = score;
    }
}
package com.jd.bean;
//課程分數
public class Score {
    //分數
    private Integer point;
    //課程名稱
    private String courseName;
    public Integer getPoint() {
        return point;
    }
    public Score add(Score other) {
        this.point += other.getPoint();
        return this;
    }
    public void setPoint(Integer point) {
        this.point = point;
    }
    public String getCourseName() {
        return courseName;
    }
    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }
}

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: