JAVA8 新特性STREAM的使用

一、简介

             一个list集合,如果我们想根据里面对象的某个字段分组,则需要遍历,然后分组;

             一个list集合,如果我们想根据里面对象的某几个字段分组,求另一个指定字段的和,则需要遍历,然后分组;

             java8提供的stream新特性,都可以以很短的代码来解决这种需求。

二、案例

2.1 情景

           比方说我有一个list集合,里面存储的是User对象,  User对象有三个字段,分别是: 姓名、地区、年龄(还可以多个字段)。

           现有如下需求:  根据名称分组;  根据名称和地区分组; 根据名称分组求对应的年龄总和; 根据名称和地区分组求对应的年龄总和;

2.2 准备

2.2.1 User对象如下:

package com.authorization.privilege;

import java.util.ArrayList;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author qjwyss
 * @date 2019/2/26
 * @description
 */
public class User {

    private String name;
    private String area;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public User() {
    }

    public User(String name, String area, Integer age) {
        this.name = name;
        this.area = area;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", area='" + area + '\'' +
                ", age=" + age +
                '}';
    }
}

 2.2.2 初始化数据

public static void main(String[] args) {

        List<User> userList = new ArrayList<>();
        userList.add(new User("zhangsan", "beijing", 10));
        userList.add(new User("zhangsan", "beijing", 20));
        userList.add(new User("lisi", "shanghai", 30));

}

2.3 需求

2.3.1 根据名称分组

// 单个字段分组
Map<String, List<User>> map1 = userList.stream().collect(Collectors.groupingBy(User::getName));
System.out.println(map1);

 结果如下:

2.3.2 根据名称和地区分组

// 多个字段分组
Map<String, List<User>> map2 = userList.stream().collect(Collectors.groupingBy(e -> e.getName() + "_" + e.getArea()));
System.out.println(map2);

结果如下:

2.3.3 根据名称分组求对应的年龄总和

// 单列求和 比方说:只根据name字段分组求和
int sum = userList.stream().mapToInt(User::getAge).sum();
System.out.println(sum);

结果如下:

2.3.4 根据名称和地区分组求对应的年龄总和

 // 多列求和 比如说:根据name字段和area字段求和
Map<String, List<User>> map3 = userList.stream().collect(Collectors.groupingBy(e -> e.getName() + "_" + e.getArea()));
List<Object> newUserList = map3.keySet().stream().map(key -> {
      User user = new User();
      user.setName(key.split("_")[0]);
      user.setArea(key.split("_")[1]);
      Integer sumAge = 0;
      List<User> eachUserList = map3.get(key);
      for (User eachUser: eachUserList) {
           sumAge += eachUser.getAge();
      }
      user.setAge(sumAge);
      return user;
}).collect(Collectors.toList());
System.out.println(newUserList);

结果如下:

猜你喜欢

转载自blog.csdn.net/qq_35206261/article/details/87946070