【java8】stream学习笔记

莱莱  金牌会员 | 2022-9-16 17:13:40 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 890|帖子 890|积分 2670

目录

一、什么是Stream

Stream是java8的新增特性,表示数据流。
二、Stream的特点


  • 不存储数据:流是基于数据源的对象,本身不存储数据。
  • 函数式编程:流的操作不会修改数据源。
  • 延迟操作:流的很多操作如filter、map是延迟执行的,只有到了终点操作才会将操作顺序执行。
  • 可以解绑:对于无线数量的流,有些操作(如limit(n)、findFirst())可以实现“短路操作”,访问到有限的元素后就可以返回。
  • 纯消费:流只能被消费一次。如果使用完了一次流,仍然用这个流对象来操作时,会报异常。
串并行

所有的流操作都可以串行执行或者并行执行。除非显示的创建并行流,否则默认创建串行流。
串行:Collection.stream()、IntStream.range(int, int)
并行:Collection.parallelStream()、
通过parallel()方法可以将串行流转换为并行流,sequential()方法将流转换为串行流
干扰数据源

流可以从非线程安全的集合中创建。当流执行时,非并发的数据源不应该改变,否则会抛出java.util.ConcurrentModificationException异常。
无状态

大部分流的操作的参数都是函数式接口,可以使用Lambda表达式实现。它们用来描述用户的行为,称之为行为参数(behavioral parameters)。
如果这些行为参数有状态,则流的操作的结果可能是不确定的,比如下面的代码:
下面代码在并行执行时,由于执行顺序的不确定性,state.s的改变时机可能不同,导致多次执行时的结果不同
  1. List<String> l = new ArrayList(Arrays.asList("one", "two", ……));
  2. class State {
  3.     boolean s;
  4. }
  5. final State state = new State();
  6. Stream<String> sl = l.stream().map(e -> {
  7.     if (state.s)
  8.         return "OK";
  9.     else {
  10.         state.s = true;
  11.         return e;
  12.     }
  13. });
  14. sl.forEach(System.out::println);
复制代码
排序

某些流的返回元素是有确定顺序的。这取决于它的数据源和中间操作。
比如List和Array创建的流是有序的,而HashSet创建的流是无序的。
sort()方法可以将流变得有序,而unordered()可以将流无序(不会打散元素)
当流有序时,如果用户并不关心顺序,可以使用unordered显示的去掉流的有序约束,可以改善某些情况下的并行性能
三、创建Stream

常见创建流的方法:

  • 通过集合Collection的Stream()或parallelStream():如list.parallelStream()、Arrays.asList(1,2,3).stream()。
  • 通过数组Arrays.stream(Object[])方法:如Arrays.stream(new int[]{1,2,3})。
  • 流的静态方法:如:Stream.of(Object[])、IntStream.range(int, int)、Stream.iterate(Object, UnaryOperator)。
  • 随机数流Random.ints()。
四、中间操作

中间操作是延迟执行的,不会修改原始数据流,在终点操作开始时才会开始执行
1. distinct

根据流中元素的hashCode()和equals()方法去除重复元素
  1. List<Integer> list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
  2. list.stream().distinct().forEach(System.out::print); // 123456
  3. System.out.println();
  4. list.forEach(System.out::print); // 12344456
复制代码
2. filter

接收predicate,过滤数据
  1. // 筛选出偶数
  2. List<Integer> list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
  3. list.stream().filter(e -> e % 2 == 0).forEach(System.out::print); // 24446
复制代码
3. map

接收一个Function实例,重新印射数据
  1. // 加1
  2. List<Integer> list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
  3. list.stream().map(e -> e + 1).forEach(System.out::print); // 23455567
复制代码
4. mapToDouble

类似map,不过结果一定要是Double类型。
类似的方法还有mapToInt(),mapToLong()
  1. // 加1.1
  2. List<Integer> list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
  3. list.stream().mapToDouble(e -> e + 1.1).forEach(System.out::println);
  4. /*
  5. 2.1
  6. 3.1
  7. 4.1
  8. 5.1
  9. 5.1
  10. 5.1
  11. 6.1
  12. 7.1
  13. */
  14. // 加1
  15. List<Integer> list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
  16. list.stream().mapToDouble(e -> e + 1).forEach(System.out::println);
  17. /*
  18. 2.0
  19. 3.0
  20. 4.0
  21. 5.0
  22. 5.0
  23. 5.0
  24. 6.0
  25. 7.0
  26. */
复制代码
4. flatmap

[code] Stream flatMap(Function
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莱莱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表