Stream API

古城微笑少年丶 2022-01-13 01:43 306阅读 0赞

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Stream API**说明**

Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 Stream API

Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

什么是 Stream

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据**Stream的是计算!”**

• ① Stream 不是集合,自己 不会存储元素。

• ② Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream 。

• ③ Stream 操作 是延迟执行的 。必须搞清楚有哪些数据才能往下执行,这 意味着他们会等到需要结果的时候才执行 。

• ④ Stream 只能“消费”一次,如果想继续做其他操作,需要重新获取 stream 对象

④更像一个高级的iterator,单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,但是可以并行化数据!**哦也!!**\(^o^)/

17a8b8cac78ab94fec29cb0c87832773d6c.jpg

b7bb870f3c6abe7de8de908c25b21454fdc.jpg

3566bb5a17d0c0f14666398ded7e22185b5.jpg

176462069ff0bab404a0fe492f5a21318be.jpg

bf47ae7c914b6fac3495804515a1b66bee3.jpg

8997ad3976cd4fd1f3e6b5345f34daf8f7b.jpg

caa3dc6979cefbf72ab3198b63e6ac933e2.jpg

b212ae7af5c9f4c58d2f2f4f7d3ab2177fb.jpg

8913f9f5548c7677787271b30afae845d2b.jpg

6dc23e598def37e9a9d9302fe6d21900a83.jpg

并行**流与串行流**

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。

Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API 可以声明性地通过 parallel() 与 sequential() 在并行流与顺序流之间进行切换。

Optional

  1. 到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。
  2. Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存nullOptional提供很多有用的方法,这样我们就不用显式进行空值检测。

Optional类的Javadoc描述如下:这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

常用方法:

Optional.empty() : 创建一个空的 Optional 实例

Optional.of(T t) : 创建一个 Optional 实例

Optional.ofNullable**(T t): t 不为 null,创建 Optional 实例,否则创建空实例**

isPresent() : 判断是否包含值

T get(): 如果调用对象包含值,返回该值,否则抛异常

orElse**(T t**) : 如果调用对象包含值,返回该值,否则返回**t**

orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值

map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()

flatMap(Function mapper):与 map 类似,要求返回值必须是Optional

  1. package day26_1;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import java.util.Optional;
  5. import java.util.Set;
  6. import java.util.stream.Collectors;
  7. import java.util.stream.Stream;
  8. import org.junit.Test;
  9. /**
  10. * Stream是流, 是工作流
  11. * 要处理批量的数据
  12. *
  13. * 1) Stream 不保存数据, 只处理数据
  14. * 2) Stream 是延迟执行的, 只有最后的执行操作下达的时候才会执行其中的操作, 并且可以有多个流式处理
  15. * 3) Stream 的消费是一次性的, 每处理一次都会产生一个新的流
  16. * 4) Stream 不会修改数据源
  17. *
  18. * Stream操作有经典的3步
  19. * 1) 创建流
  20. * 2) 一系列的中间操作, 流水线, (可以省略)
  21. * filter(Predicate p) // 流中的每个数据都要经过判定的判定, 如果判断结果为真的留下, 假的丢弃。
  22. * distinct(); 去重依据的是对象的hashCode和equals
  23. * limit(int size) 限制最多的个数
  24. * sorted() 自然排序
  25. * sorted(Comparator com) 定制排序
  26. * map(Function fun) 把流中的所有数据转换为另外的类型并产生新流
  27. *
  28. * 3) 终止流
  29. * Optional<T> findFirst(); // 返回流中的第一个元素
  30. * long count();
  31. * reduce(BinaryOperator bo) ;// 二元运算, 两输入一输出, 最后产生一个结果
  32. * collect()收集
  33. *
  34. * Optional 的正确用法 , 尽量避免空指针
  35. * orElse(非空);
  36. */
  37. public class SteamTest {
  38. @Test
  39. public void test13() {
  40. Stream<Student> stream = StudentData.getList().stream();
  41. //stream.parallel();
  42. Set<Student> set = stream.distinct().collect(Collectors.toSet()); // toList
  43. for (Student student : set) {
  44. System.out.println(student);
  45. }
  46. }
  47. @Test
  48. public void test12() {
  49. Stream<Student> stream = StudentData.getList().stream();
  50. // 找出最高分
  51. Optional<Double> optional = stream.distinct().map(t -> t.getScore()).reduce((t1, t2) -> t1 > t2 ? t1 : t2);
  52. System.out.println(optional.orElse(101.0));
  53. }
  54. @Test
  55. public void test11() {
  56. Stream<Student> stream = StudentData.getList().stream();
  57. // 统计有几个五年级同学
  58. long count = stream.distinct().filter(t -> t.getGrade() == 5).count();
  59. System.out.println(count);
  60. }
  61. @Test
  62. public void test10() {
  63. Stream<Student> stream = StudentData.getList().stream();
  64. Optional<Student> findFirst = stream.distinct().filter(t -> t.getGrade() == 3).findFirst();
  65. //System.out.println(findFirst.get());
  66. System.out.println(findFirst.orElse(new Student()).toString());
  67. }
  68. @Test
  69. public void test9() {
  70. Stream<Student> stream = StudentData.getList().stream();
  71. stream.distinct().map(t -> t.getScore()).forEach(System.out::println);
  72. }
  73. @Test
  74. public void test8() {
  75. Stream<Student> stream = StudentData.getList().stream();
  76. stream.sorted((t1, t2) -> t1.getGrade() - t2.getGrade()).forEach(System.out::println);
  77. }
  78. @Test
  79. public void exer2() {
  80. //找出3年级中没有及格的同学, 倒序排序, 并取出前2个3年级同学.
  81. Stream<Student> stream = StudentData.getList().stream();
  82. stream.distinct().filter(t->t.getGrade()==3).filter(t->t.getScore()<60)
  83. .sorted((t1, t2) -> (int)(t2.getScore() - t1.getScore())).limit(2).forEach(System.out::println);
  84. }
  85. @Test
  86. public void test7() {
  87. Stream<Student> stream = StudentData.getList().stream();
  88. stream.distinct().limit(50).forEach(System.out::println);
  89. }
  90. @Test
  91. public void test6() {
  92. Stream<Student> stream = StudentData.getList().stream();
  93. stream.distinct().forEach(System.out::println);
  94. }
  95. @Test
  96. public void test5() {
  97. Stream<Student> stream = StudentData.getList().stream();
  98. // 所有姓张的并且及格的
  99. stream.filter(t -> t.getScore() >= 60).filter(t -> t.getName().startsWith("张")).forEach(System.out::println);
  100. }
  101. @Test
  102. public void exer1() {
  103. // 找出3年级没有及格的同学
  104. Stream<Student> stream = StudentData.getList().stream();
  105. stream.filter(t -> t.getGrade() == 3).filter(t -> t.getScore() < 60).forEach(System.out::println);
  106. }
  107. @Test
  108. public void test4() {
  109. // 无限流
  110. //Stream<Integer> generate = Stream.generate(() -> 100);
  111. Stream<Double> generate = Stream.generate(Math::random);
  112. generate.forEach(System.out::println);
  113. }
  114. @Test
  115. public void test3() {
  116. // 基于一些散数据
  117. Stream<String> stream = Stream.of("abc", "xxx", "zzz", "yyy", "qq");
  118. stream.forEach(System.out::println);
  119. }
  120. @Test
  121. public void test2() {
  122. // 基于数组
  123. Integer[] arr = {1, 3, 8, 9, 10};
  124. Stream<Integer> stream = Arrays.stream(arr);
  125. //stream.forEach(t -> System.out.println(t));
  126. stream.forEach(System.out::println); // 方法引用的方式
  127. }
  128. @Test
  129. public void test1() {
  130. // 基于集合获取流
  131. List<Student> list = StudentData.getList();
  132. Stream<Student> stream = list.stream();
  133. // 终止流 , forEach(Consumer con); // 把流中的每个对象都经过这个消费器消费一下
  134. stream.forEach(t -> System.out.println(t));
  135. //stream.forEach(t -> System.out.println(t)); 必须一次性使用流
  136. }
  137. }

转载于:https://my.oschina.net/architectliuyuanyuan/blog/3048182

发表评论

表情:
评论列表 (有 0 条评论,306人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Streaming API

    Streaming API 概述: Stream是jdk8增加的一个接口,该接口提供了一些对容器数据进行操作的规则,有了这些规则 就可以不通过遍历容器就可以以完成对

    相关 Stream API

    Stream API 首先要理解Stream的概念,说实话这点确实非常的不好理解,尤其是Java IO也有Stream的概念,所以很容易导致混淆.

    相关 Stream API

    以前对集合中元素进行操作的时候需要一个一个遍历的去做,找出符合条件的数据,这样做真的不要太繁琐= =。 sql中却有很强的筛选信息的能力,而且也可以返回你想要的结果。 借鉴