java8新特性(五) stream流

什么是stream

  • Stream 中⽂称为 “流”,通过将集合转换为这么⼀种叫做 “流”的元素队列,通过声明性⽅式,

  • 能够对集合中的每个元素进⾏⼀系列并⾏或串⾏的流⽔线操作

  • 元素是特定类型的对象,所以元素集合看作⼀种流, 流在管道中传输, 且可以在管道的节点上进⾏处理, ⽐如 排序,聚合,过滤等操作
    在这里插入图片描述

  • 操作详情

    • 数据元素便是原始集合,如List、Set、Map等
    • ⽣成流,可以是串⾏流stream() 或者并⾏流 parallelStream()
    • 中间操作,可以是 排序,聚合,过滤,转换等
    • 终端操作,很多流操作本身就会返回⼀个流,所以多个操作可以直接连接起来,最后统⼀进⾏收集
    • 概览stream接⼝源码
  • map函数
    将流中的每⼀个元素 T 映射为 R(类似类型转换)
    上堂课的例⼦就是,类似遍历集合,对集合的每个对象做处理
    场景:转换对象,如javaweb开发中集合⾥⾯的DO对象转换为DTO对象

  • filter函数
    ⽤于通过设置的条件过滤出元素
    场景:主要⽤于筛选过滤出符合条件的元素

  • sorted函数
    sorted() 对流进⾏⾃然排序, 其中的元素必须实现Comparable 接⼝

List<String> list = Arrays.asList("springboot", "springcloud",
"redis", "git", "netty", "java", "html", "docker");
List<String> resultList =
list.stream().sorted().collect(Collectors.toList());
  • sorted(Comparator<? super T> comparator) ⽤来⾃定义升降序
List<String> list = Arrays.asList("springboot", "springcloud",
"redis", "git", "netty", "java", "html", "docker");
//根据⻓度进⾏排序
//List<String> resultList =
list.stream().sorted(Comparator.comparing(obj ->
obj.length())).collect(Collectors.toList());
//List<String> resultList =
list.stream().sorted(Comparator.comparing(obj ->
obj.length(),Comparator.reverseOrder())).collect(Collectors.toList()
);
//List<String> resultList =
list.stream().sorted(Comparator.comparing(String::length).reversed()
).collect(Collectors.toList());
System.out.println(resultList);
  • limit函数
    截断流使其最多只包含指定数量的元素
List<String> list = Arrays.asList("springboot", "springcloud",
"redis", "git", "netty", "java", "html", "docker");
//limit截取
List<String> resultList =
list.stream().sorted(Comparator.comparing(String::length).reversed()
).limit(3).collect(Collectors.toList());
System.out.println(resultList);
  • allMatch函数
    检查是否匹配所有元素,只有全部符合才返回true
List<String> list = Arrays.asList("springboot", "springcloud", "redis",
"git", "netty", "java", "html", "docker");
boolean flag = list.stream().allMatch(obj->obj.length()>1);
System.out.println(flag);
  • anyMatch函数
    检查是否⾄少匹配⼀个元素
List<String> list = Arrays.asList("springboot", "springcloud", "redis",
"git", "netty", "java", "html", "docker");
boolean flag = list.stream().anyMatch(obj->obj.length()>18);
System.out.println(flag);
  • max和min函数
    最⼤值和最⼩值
List<Student> list = Arrays.asList(new Student(32),new
Student(33),new Student(21),new Student(29),new Student(18));
//list.stream().max(Comparator.comparingInt(Student::getAge));
//最⼤
Optional<Student> optional = list.stream().max((s1, s2)-
>Integer.compare(s1.getAge(),s2.getAge()));
//最⼩
Optional<Student> optional = list.stream().min((s1, s2)-
>Integer.compare(s1.getAge(),s2.getAge()));
System.out.println(optional.get().getAge());
  • 并⾏流parallelStream

  • 为什么会有这个并⾏流

    • 集合做重复的操作,如果使⽤串⾏执⾏会相当耗时,因此⼀般会采⽤多线程来加快, Java8的paralleStream⽤fork/join框架提供了并发执⾏能⼒
    • 底层原理
      线程池(ForkJoinPool)维护⼀个线程队列
      可以分割任务,将⽗任务拆分成⼦任务,完全贴合分治思想
  • 问题

    • paralleStream并⾏是否⼀定⽐Stream串⾏快?
      错误,数据量少的情况,可能串⾏更快,ForkJoin会耗性能
    • 多数情况下并⾏⽐串⾏快,是否可以都⽤并⾏
      不⾏,部分情况会有线程安全问题,parallelStream⾥⾯使⽤的外部变量,⽐如集合⼀定要使⽤线程安全集合,不然就会引发多线程安全问题
  • reduce操作

    • 常⽤⽅法⼀
Optional<T> reduce(BinaryOperator<T> accumulator);
  • accumulator 计算的累加器
    • 例⼦: 第⼀个元素相加和第⼆个元素相加,结果再和第三个元素相加,直到全部相加完成
int value = Stream.of(1, 2, 3, 4, 5).reduce((item1, item2) -> item1+ item2).get();
  • 常⽤⽅法二
T reduce(T identity, BinaryOperator<T> accumulator);
  • identity ⽤户提供⼀个循环计算的初始值
  • accumulator 计算的累加器
  • 例⼦: 100作为初始值,然后和第⼀个元素相加,结果在和第⼆个元素相加,直到全部相加完成
int value = Stream.of(1, 2, 3, 4,5).reduce(100, (sum, item) -> sum + item);
  • forech
List<Student> results = Arrays.asList(new Student(32),new
Student(33),new Student(21),new Student(29),new Student(18));
results.forEach(obj->{
 System.out.println(obj.toString());
});
  • 注意事项
    • 不能修改包含外部的变量的值
    • 不能⽤break或者return或者continue等关键词结束或者跳过循环

collector收集器

  • collect()⽅法的作⽤
    • ⼀个终端操作, ⽤于对流中的数据进⾏归集操作,collect⽅法接受的参数是⼀个Collector
  • Collectors 的作⽤
    ⼯具类,提供了很多常⻅的收集器实现
Collectors.toList()
ArrayList::new,创建⼀个ArrayList作为累加器
List::add,对流中元素的操作就是直接添加到累加器中
reduce操作, 对⼦任务归集结果addAll,后⼀个⼦任务的结果直接全部添加到
前⼀个⼦任务结果中
CH_ID 是⼀个unmodifiableSet集合
Collectors.toMap()
Collectors.toSet()
Collectors.toCollection() :⽤⾃定义的实现Collection的数据结构收集
Collectors.toCollection(LinkedList::new)
Collectors.toCollection(CopyOnWriteArrayList::new)
Collectors.toCollection(TreeSet::new)
  • joining函数
3种重载⽅法
Collectors.joining()
Collectors.joining("param")
Collectors.joining("param1", "param2", "param3")
  • 说明:
    该⽅法可以将Stream得到⼀个字符串, joining函数接受三个参数,分别表示 元素之间的连接符、前缀和后缀。

  • partitioningBy分组

  • 练习: 根据list⾥⾯进⾏分组,字符串⻓度⼤于4的为⼀组,其他为另外⼀组

List<String> list = Arrays.asList("java", "springboot",
"HTML5","nodejs","CSS3");
Map<Boolean, List<String>> result =
list.stream().collect(partitioningBy(obj -> obj.length() > 4));
  • group by分组
    todo 案例待补充

  • summarizingIn
    todo 案例待补充

猜你喜欢

转载自blog.csdn.net/lin819747263/article/details/102733338