Java 8 Stream玩转集合的筛选、归约、分组、聚合

参考地址 juejin.cn/post/7064757819165114404

Java 8 Stream玩转集合的筛选、归约、分组、聚合

Java 8 Stream玩转集合的筛选、归约、分组、聚合
先贴上几个案例,水平高超的同学可以挑战一下:

  1. 从员工集合中筛选出salary大于8000的员工,并放置到新的集合里。

  2. 统计员工的最高薪资、平均薪资、薪资之和。

  3. 将员工按薪资从高到低排序,同样薪资者年龄小者在前。

  4. 将员工按性别分类,将员工按性别和地区分类,将员工按薪资是否高于8000分为两部分。

用传统的迭代处理也不是很难,但代码就显得冗余了,跟Stream相比高下立判。Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利。

那么什么是Stream

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

Stream可以由数组或集合创建,对流的操作分为两种:

  1. 中间操作,每次返回一个新的流,可以有多个。

  2. 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

另外,Stream有几个特性:

  1. stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。

  2. stream不会改变数据源,通常情况下会产生一个新的集合或一个值。

  3. stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

Stream可以通过集合数组创建。


/**
 * @author zhangxiao
 * @qq 490433117
 * @create_date 2022/6/13 10:52
 */package com.xiao.test;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zhangxiao
 * @date 2022/6/13 10:52
 */public class StreamDemo2 {
  public static void main(String[] args) {
  List<Person> personList = new ArrayList<Person>();
  personList.add(new Person("Tom", 8900, 20, "male", "New York"));
  personList.add(new Person("Jack", 7000, 30, "male", "Washington"));
  personList.add(new Person("Lily", 7800, 40, "female", "Washington"));
  personList.add(new Person("Anni", 8200, 50, "female", "New York"));
  personList.add(new Person("Owen", 9500, 60, "male", "New York"));
  personList.add(new Person("Alisa", 7900, 70, "female", "New York"));

// 问题1.筛选员工中工资高于8000的人,并形成新的集合。 形成新集合依赖collect(收集),后文有详细介绍。
  List<String> getName = personList.stream().filter(s -> s.getSalary() > 8000).map(s ->s.getName()).collect(Collectors.toList());
//        System.out.println(getName);

// 问题2\. 获取员工工资最高的人
  Person person = personList.stream().max(Comparator.comparingInt(Person::getSalary)).get();
//        System.out.println(person);

// 问题3.将员工的薪资全部增加1000, 返回对象集合

  List<Person> collect = personList.stream().map(ss -> {
  ss.setSalary(ss.getSalary() + 1000);
  return ss;
 }).collect(Collectors.toList());

//        System.out.println(collect);

// 问题4\. 求所有员工的工资之和和最高工资。

  Integer integer = personList.stream().map(Person::getSalary).reduce(Integer::sum).get();
  System.out.println(integer);
  // 最高工资
  Integer reduce = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(), Integer::max);
  Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
//        System.out.println(max);
//        System.out.println(reduce);
// 问题5\. 统计员工人数、平均工资、工资总额、最高工资。

  Long collect1 = personList.stream().collect(Collectors.counting());
  //System.out.println(collect1);
  Double collect2 = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
//        System.out.println(collect2);

// 问题6\. 将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组

  Map<String, Map<String, List<Person>>> collect3 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));

//        System.out.println(collect3);

// 问题7\. 将所有的员工名字拼接
  String collect4 = personList.stream().map(Person::getName).collect(Collectors.joining(","));
  System.out.println(collect4);
 }

}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Person {
  private String name; // 姓名
  private int salary; // 薪资
  private int age; // 年龄
  private String sex; //性别
  private String area; // 地区

}
本作品采用《CC 协议》,转载必须注明作者和本文链接
zhaozhangxiao
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!