Stream流基本语法

本文详细介绍了Java Stream API的基本概念、特性、优点,以及如何创建顺序流和并行流。通过实例展示了filter、map、reduce、collect等核心操作,包括过滤、聚合、映射、累积、收集等,还涉及了统计和分组功能。通过Stream API,代码变得更加简洁高效,尤其在处理大数据时能大幅提升性能。
摘要由CSDN通过智能技术生成

Stream流基本语法

什么是Stream?

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

Stream特性

通过Lambda 表达式对集合进行便利、高效的聚合操作,或者大批量数据操作,Stream不仅可以通过串行的方式实现数据操作,还可以通过并行的方式处理大批量数据,提高数据的处理效率。

Stream优点
  1. 代码变得更优雅简洁
  2. 处理大数据并行流要远高于传统批量处理方式
  3. 有多种聚合操作

代码编写

创建顺序流
List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("王武",12L,"男"));
// 顺序流
Stream<User> stream = list.stream();
创建并行流
List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("王武",12L,"男"));
// 并行流
Stream<User> stream = list.parallelStream();

顺序流和并行流区别: 顺序流只会有一个主线程执行流操作,并行流内部会用多线程的方式对流执行操作并且顺序会被打乱

  • 如果不存在线程安全,并且是数据量较大的建议使用并行。
  • 相反数据量比较小的建议使用顺序流,顺序执行会比并行更快,因为创建线程池和其他的资源也是需要时间的。
  • 如果对顺序有要求的不建议使用并行,因为并行执行完成,流顺序会被打乱。
filter(过滤)

案例01:过滤出年龄为10岁的人员

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("王武",12L,"男"));
list.stream().filter(t -> t.getAge() == 10).forEach(System.out::println);

结果:User(name=张三, age=10, hha=男)

案例02:过滤出年龄为10岁的人员并且性别为男性的人员

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",10L,"女"));
list.add(new User("王武",10L,"男"));
list.stream().filter(t -> t.getAge() == 10 && t.getHha().equals("男")).forEach(System.out::println);

结果:User(name=张三, age=10, hha=男) User(name=王武, age=10, hha=男)

聚合

min(最小元素)
案例01:返回年龄最小的人员

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("王武",12L,"男"));
String name = list.stream().min(Comparator.comparing(User::getAge)).get().getName();
System.out.println("年龄最小的人员为:" + name);

结果:年龄最小的人员为:张三

max(最大元素)
案例02:找出名字最长的人员

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
String name = list.stream().max(Comparator.comparing(t -> t.getName().length())).get().getName();
System.out.println("名字最长的人员为:"+name);

结果:名字最长的人员为:张三丰

count(总数)
案例03:获取人员中性别为男性的共有多少人

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
long count = list.stream().filter(t -> t.getHha().equals("男")).count();
System.out.println("男性人员共有:"+count);

结果:男性人员共有:2

映射

map:官方说明-返回由给定函数应用于此流的元素的结果组成的流,其实就是接收一个函数式的参数,并将元素的结果返回一个新流
案例01:返回人员所有的名称

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
List<String> names = list.stream().map(t -> t.getName()).collect(Collectors.toList());
System.out.println(names);

结果:[张三, 李四, 张三丰]

案例02:将男性人员的年龄加一岁

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
List<User> lists = list.stream().filter(b -> b.getHha().equals("男")).map(t -> {
            t.setAge(t.getAge() + 1);
            return t;
}).collect(Collectors.toList());
System.out.println(lists);

结果:[User(name=张三, age=11, hha=男), User(name=张三丰, age=13, hha=男)]

reduce(累积)

reduce:可以将一个流合为一个元素,可以对集合求和 乘积 求最大小值等。

List<Integer> list = Arrays.asList(1,2,3,4,5,6);
// 求和
Integer sum = list.stream().reduce(0,Integer::sum);
System.out.println("求和数 = " + sum);
// 乘积
Optional<Integer> chj = list.stream().reduce((x, y) -> x * y);
System.out.println("乘积数 = " + chj.get());
// 最大值
Integer zud = list.stream().reduce(1,Integer::max);
System.out.println("最大数 = " + zud);
// 最小值
Integer zux = list.stream().reduce(1,Integer::min);
System.out.println("最小数 = " + zux);

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
// 求和
long sum = list.stream().map(User::getAge).reduce(0L,Long::sum);
System.out.println("求和 = " + sum);
// 最大值
long reduce = list.stream().map(User::getAge).reduce(1L,Long::max);
System.out.println("求最大年龄 = " + reduce);

结果:
求和数 = 21
乘积数 = 720
最大数 = 6
最小数 = 1
求和 = 33
求最大年龄 = 12

collect(收集)

collect:对流的一个收集,最后把流变成一个新的集合或者一个值

toList/toSet/toMap

案例01:将过滤后的集合 收集到新的流中

List<Integer> in = Arrays.asList(1,1,2,3,4,5,5,6);
List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
List<User> lists = list.stream().filter(t -> t.getHha().equals("男")).collect(Collectors.toList());
System.out.println(lists);
Set<Integer> set = in.stream().collect(Collectors.toSet());
System.out.println(set);
Map<?, User> map = list.stream().filter(t -> t.getHha().equals("男")).collect(Collectors.toMap(User::getName, t -> t));
System.out.println(map);

结果:
[User(name=张三, age=10, hha=男), User(name=张三丰, age=12, hha=男)]
[1, 2, 3, 4, 5, 6]
{张三=User(name=张三, age=10, hha=男), 张三丰=User(name=张三丰, age=12, hha=男)}

统计
  • 个数:count
  • 平均值:averagingInt、averagingLong、averagingDouble
  • 最值:maxBy、minBy
  • 求和:summingInt、summingLong、summingDouble
List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
// 人员数量
Long count = list.stream().collect(Collectors.counting());
// 平均年龄
Double average = list.stream().collect(Collectors.averagingDouble(User::getAge));
// 最大年龄
Optional<Long> max = list.stream().map(User::getAge).collect(Collectors.maxBy(Long::compare));
// 年龄之和
Long sum = list.stream().collect(Collectors.summingLong(User::getAge));

System.out.println("人员数量:" + count);
System.out.println("平均年龄:" + average);
System.out.println("最大年龄:" + max.get());
System.out.println("年龄之和:" + sum);

结果:
人员数量:3
平均年龄:11.0
最大年龄:12
年龄之和:33

分组
List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
// 年龄大于10岁的分为一组
Map<Boolean, List<User>> part = list.stream().collect(Collectors.partitioningBy(t -> t.getAge() > 10));
// 按性别分组
Map<String, List<User>> group1 = list.stream().collect(Collectors.groupingBy(User::getHha));
// 先按性别分组,再按姓名分组
Map<String, Map<String, List<User>>> group2 = list.stream().collect(Collectors.groupingBy(User::getHha, Collectors.groupingBy(t -> t.getName())));
System.out.println("年龄大于10岁的分为一组:" + part);
System.out.println("按性别分组:" + group1);
System.out.println("先按性别分组,再按姓名分组:" + group2);

结果:
年龄大于10岁的分为一组:{false=[User(name=张三, age=10, hha=男)], true=[User(name=李四, age=11, hha=女), User(name=张三丰, age=12, hha=男)]}
按性别分组:{女=[User(name=李四, age=11, hha=女)], 男=[User(name=张三, age=10, hha=男), User(name=张三丰, age=12, hha=男)]}
先按性别分组,再按姓名分组:{女={李四=[User(name=李四, age=11, hha=女)]}, 男={张三=[User(name=张三, age=10, hha=男)], 张三丰=[User(name=张三丰, age=12, hha=男)]}}

joining

案例01:获取集合name字段 并将字段用逗号分隔返回字符串

List<User> list = new ArrayList<>();
list.add(new User("张三",10L,"男"));
list.add(new User("李四",11L,"女"));
list.add(new User("张三丰",12L,"男"));
String collect1 = list.stream().map(t -> t.getName()).collect(Collectors.joining(","));
System.out.println("逗号分隔:"+collect1);
String collect2 = list.stream().map(t -> t.getName()).collect(Collectors.joining("|"));
System.out.println("竖线分隔:"+collect2);

结果:
逗号分隔:张三,李四,张三丰
竖线分隔:张三|李四|张三丰

ps:一只小菜鸟 一直在学习 从未敢停止

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TianYuuuuuuuuuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值