当前位置: 首页 > news >正文

集合框架拓展--stream流的使用

Stream(JDK8新特性)

什么是Stream?

  • 也叫stream流,是JDK8开始新增的一套API(java.util.stream.*),可以用于操作集合或数组中的数据

  • 优势:Stream流大量地结合了Lambda的语法风格来编程,提供了一种更强大,更加简单的方式操作集合或者数组的数据,代码更简洁,可读性更好(比如:从集合中筛选数据,遍历数据)

案例:体验stream流

需求:

  • 把集合中所有以''张''开头而且是三个字的元素存储到一个新的集合中

代码展示:

 package com.lyc.steam;​import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.stream.Collectors;import java.util.stream.Stream;​public class Test1 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"张三丰","张无忌","周芷若","赵敏");//把集合中所有以''张''开头而且是三个字的元素存储到一个新的集合中//原做法:ArrayList<Object> list1 = new ArrayList<>();list.forEach(s -> {if(s.startsWith("张") && s.length() == 3){list1.add(s);}});System.out.println(list1);//stream流优化:List<String> list2 = list.stream().filter(s -> s.startsWith("张") && s.length() == 3).toList();System.out.println(list2);}}

Stream流的使用步骤

  1. 获取数据源的stream流,相当于得到了数据源的一条流水线

  2. 调用流水线的各种中间方法去进行数据处理

  3. 获取处理的结果,调用一些常见的终结方法

stream的常用方法

获取stream流方法
  • 获取集合的Stream流,

Collection提供的如下方法说明
default Stream <E> stream()获取当前对象的stream流
  • 获得数组的Stream流

Arrays类提供的如下方法说明
public static <T> Stream<T> stream(T[] array)获取当前数组的Stream流
Stream类提供的如下方法说明
public static<T> Stream<T> of(T...values)获取当前接受数据的stream流

案例展示:

 public static void main(String[] args) {//如何获取List集合的stream流?List<String> list = new ArrayList<>();Collections.addAll(list,"张三丰","张无忌","周芷若","赵敏");Stream<String> stream = list.stream();//如何获得Set集合的stream流?Set<String> set = new HashSet<>();Collections.addAll(set,"张三丰","张无忌","周芷若","赵敏");Stream<String> stream1 = set.stream();stream1.filter(s->s.contains("张")).forEach(System.out::println);//如何获得Map集合的stream流?Map<String,Double> map = new HashMap<>();map.put("张三丰",9.9);map.put("张无忌",9.8);map.put("周芷若",9.7);map.put("赵敏",9.6);//map.entrySet()返回的是一个Set集合,所以可以转换为stream流Stream<Map.Entry<String, Double>> stream2 = map.entrySet().stream();stream2.filter(s->s.getValue()>9.5 && s.getKey().contains("张")).forEach(System.out::println);​//如何获取数组的数据流String[] arr = {"张三丰","张无忌","周芷若","赵敏"};//直接使用Array工具类的静态方法Stream<String> stream3 = Arrays.stream(arr);//使用Stream工具类Stream<String> arr1 = Stream.of(arr);
Stream流中间方法
  • 中间方法是指调用完成后返回新的Stream流,可以继续使用(支持链式编程)

方法名说明
Stream<T> filter(Predicate predicate)用于对流中的数据进行过滤
Stream<T> limit(long maxSize)获取前几个元素
Stream<T> skip(long n)跳过前几个元素
static <T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流
Stream<T> distinct()去重
Stream<T> sorted()排序
Stream<T> sorted(Comparator comparator)根据提供的Comparator进行排序
<R> Stream<R> map(Function mapper)对元素进行加工,并返回对应的新流
IntStream mapToInt(ToIntFunction mapper)返回一个IntStream其中包含将给定函数应用于此流的元素的结果

代码测试:

 
  public static void main(String[] args) {List<Double> sorces = new ArrayList<>();Collections.addAll(sorces, 88.5, 99.5, 100.0, 60.5, 70.5, 80.5, 90.5, 50.5, 40.5, 30.5, 20.5);//需求1:找出成绩大于六十的学生成绩,并升序后输出 终结方法:foreachsorces.stream().filter(s->s>60).sorted().forEach(System.out::println);System.out.println("----------------------------------------------------------");ArrayList<Student> students = new ArrayList<>();students.add(new Student("张三", 18, 170.7));students.add(new Student("李四", 19, 180.7));students.add(new Student("李四", 19, 180.7));students.add(new Student("王五", 20, 190.7));students.add(new Student("赵六", 21, 200.7));students.add(new Student("钱七", 22, 210.7));students.add(new Student("孙八", 23, 220.7));//需求2:找出年龄大于等于20,小于30的学生,并按照年龄降序排序输出students.stream().filter(s->s.getAge()>=20 && s.getAge()<30).sorted((s1,s2)->s2.getAge()-s1.getAge()).forEach(System.out::println);System.out.println("-------------------------------------------------------");//需求3:找出身高最高的三名学生 limit 方法:限制数量students.stream().sorted((s1,s2)->s2.getHeight().compareTo(s1.getHeight())).limit(3).forEach(System.out::println);System.out.println("------------------------------------------------------------");//需求4:取出身高倒数的2名学生,并输出 skip方法:跳过students.stream().sorted((s1,s2)->s2.getHeight().compareTo(s1.getHeight())).skip(students.size()-2).forEach(System.out::println);System.out.println("------------------------------------------------------------");//需求5:找出身高大于等于180cm的学生的名字,要求去除重复的名字,在输出 map方法:映射,将student对象的name属性映射为字符串 distinct 方法:去重students.stream().filter(s->s.getHeight()>=180).distinct().map(Student::getName).forEach(System.out::println);System.out.println("----------------------------------------------------------------");//distinct()方法:去重,自定义类型的对象,必须重写hashCode()和equals()方法,才能去重students.stream().filter(s->s.getHeight()>=180).distinct().forEach(System.out::println);System.out.println("---------------------------------------------------------");//需求6:合并以下的两个流 concat 方法:连接两个流Stream<String> st1 = Stream.of("张三", "李四", "王五");Stream<String> st2 = Stream.of("赵六", "钱七", "孙八");Stream<String> stream = Stream.concat(st1, st2);stream.forEach(System.out::println);​}}
stream流的终结方法
  • 终结方法是指调用完成后,不会再返回新的stream流,没法在使用流了

stream提供的常用终结方法说明
void forEach(Consmer)对此流运算后的元素执行便历
long count()统计此流运算后的元素个数
Optional <T> max(Comparator<? super T> Comparator)获取此流运算后的最大值元素
Optional <T> min(Comparator<? super T> Comparator)获取此流运算后的最小值元素
  • 收集Stream流:就是把Stream流操作后的结果转到集合或者数组中去返回。

  • stream流:方便操作集合/数组的手段 集合/数组:才是开发的目的

    stream提供的常用终结方法说明
    R collect(Collector collector)把流处理后的结果收集到一个指定的集合中去
    Object[] toArray()把流处理后的结果收集到一个数组中去

代码展示:

 package com.lyc.steam;​import com.lyc.pojo.Student;​import java.util.*;import java.util.stream.Collectors;​//测试stream流的终结方法public class Test4 {public static void main(String[] args) {ArrayList<Student> students = new ArrayList<>();students.add(new Student("张三", 18, 170.7));students.add(new Student("李四", 19, 180.7));students.add(new Student("李四", 19, 180.7));students.add(new Student("王五", 20, 190.7));students.add(new Student("赵六", 21, 200.7));students.add(new Student("钱七", 22, 210.7));students.add(new Student("孙八", 23, 220.7));//需求1:请计算出身高超过180的学生人数long count = students.stream().filter(s -> s.getHeight() > 180).count();System.out.println(count);System.out.println("-----------------------------------------------");//需求2:找出身高最高的学生对象,并输出Student max = students.stream().max((s1, s2) -> s1.getHeight().compareTo(s2.getHeight())).get();System.out.println(max);System.out.println("-------------------------------------------");//需求3:找出身高最矮的学生对象,并输出Student min = students.stream().min((s1, s2) -> s1.getHeight().compareTo(s2.getHeight())).get();System.out.println(min);System.out.println("----------------------------------------------");//需求4:身高超过190的学生对象,放在一个新的集合中返回// toList()方法:将流中的元素收集到一个List集合中,返回一个List集合//流,只能使用一次,所以不能再使用filter()方法,否则会报错List<Student>  students1 =  students.stream().filter(s->s.getHeight()>190).toList();Set<Student> collect = students.stream().filter(s -> s.getHeight() > 190).collect(Collectors.toSet());System.out.println(students1);System.out.println(collect);System.out.println("--------------------------------------------------");//需求5:找出身高大于等于190cm的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回。 key:学生姓名,value:学生身高,toMap()方法:将流中的元素收集到一个Map集合中,返回一个Map集合Map<String, Double> map = students.stream().filter(s -> s.getHeight() >= 170).distinct().collect(Collectors.toMap(Student::getName, Student::getHeight));System.out.println(map);System.out.println("----------------------------------------------");//需求6:找出身高大于等于180cm的学生对象,并把学生对象的名字存入到一个数组返回。String[] array = students.stream().filter(s -> s.getHeight() >= 180).map(Student::getName).toArray(len->new String[len]);System.out.println(Arrays.toString(array));}}​

注:流只能收集一次,不要想着将重复的流代码抽取封装成工具,会报错

流只是我们用来简化代码的工具,只是手段,变成集合/数组才是目的!

希望对大家有所帮助!

相关文章:

  • 生成式AI对话中提示词策略:明确问题、明确目标和提供背景信息是最有效的策略
  • 一招解决所以Maven找不到依赖包的问题
  • Java优雅实现判空方法
  • 在 QCustomPlot中自定义绘图元素
  • 【CentOs】构建云服务器部署环境
  • ClickHouse核心架构设计
  • day47——平方数之和(LeetCode-633)
  • STM32(M4)入门:GPIO与位带操作(价值 3w + 的嵌入式开发指南)
  • FFmpeg:M3U8的AES加密
  • 《Android 应用开发基础教程》——第三章:布局管理与 UI 组件详解
  • 多模态大语言模型arxiv论文略读(三十一)
  • 机器学习 Day12 集成学习简单介绍
  • [Windows]_[VS2017]_[如何进行远程调试程序]
  • POSIX标准系统调用详解:从概念到实践
  • 破解吞咽困境!进行性核上性麻痹患者的科学饮食方案
  • 62页华为IPD-MM流程:市场调研理论与实践方案精读【附全文阅读】
  • Linux 网络基础(二) (传输协议层:UDP、TCP)
  • 【算法提高】单源最短路的建图方式
  • Linux系统编程---孤儿进程与僵尸进程
  • UML统一建模
  • 京津冀“飘絮之困”如何破解?专家坦言仍面临关键技术瓶颈
  • 中国体育报关注徐梦桃、王曼昱、盛李豪等获评全国先进工作者:为建设体育强国再立新功
  • 买新房可申领学位,广州南沙出台购房入学政策
  • 解放日报头版:人民城市共建共享展新卷
  • 众信旅游:去年盈利1.06亿元,同比增长228.18%
  • 四川省社科联期刊:不建议在读硕士、博士将导师挂名为第一作者