【java8】stream学习笔记()

  本篇文章为你整理了【java8】stream学习笔记()的详细内容,包含有 【java8】stream学习笔记,希望能帮助你了解 【java8】stream学习笔记。

  目录一、什么是Stream二、Stream的特点串并行干扰数据源无状态排序三、创建Stream四、中间操作1. distinct2. filter3. map4. mapToDouble4. flatmap5. limit6. skip7. peek8. sorted五、终点操作1. Match2. count3. collect4. find5. forEach6. max、min7. reduce8. toArray()六、参考文档

  一、什么是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的改变时机可能不同,导致多次执行时的结果不同

  

List String l = new ArrayList(Arrays.asList("one", "two", ……));

 

  class State {

   boolean s;

  final State state = new State();

  Stream String sl = l.stream().map(e - {

   if (state.s)

   return "OK";

   else {

   state.s = true;

   return e;

  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()方法去除重复元素

  

List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);

 

  list.stream().distinct().forEach(System.out::print); // 123456

  System.out.println();

  list.forEach(System.out::print); // 12344456

  

 

  2. filter

  接收predicate,过滤数据

  

// 筛选出偶数

 

  List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);

  list.stream().filter(e - e % 2 == 0).forEach(System.out::print); // 24446

  

 

  3. map

  接收一个Function实例,重新印射数据

  

// 加1

 

  List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);

  list.stream().map(e - e + 1).forEach(System.out::print); // 23455567

  

 

  4. mapToDouble

  类似map,不过结果一定要是Double类型。

  类似的方法还有mapToInt(),mapToLong()

  

// 加1.1

 

  List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);

  list.stream().mapToDouble(e - e + 1.1).forEach(System.out::println);

  // 加1

  List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);

  list.stream().mapToDouble(e - e + 1).forEach(System.out::println);

  

 

  4. flatmap

  

 R Stream R flatMap(Function ? super T, ? extends Stream ? extends R mapper);

 

  

 

  将映射后的元素放在一个新的流中。

  类似的方法还有flatMapToDouble、flatMapToInt、flatMapToLong

  

List String list = Arrays.asList("1233", "2444", "562","78");

 

  list.stream()

   .flatMap(e - Arrays.stream(e.split("2")))

   .forEach(System.out::println);

  

 

  5. limit

  限制流中元素的数量。对于有序并行流,性能消耗更高

  

List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);

 

  list.stream().limit(5).forEach(System.out::print); // 12344

  

 

  6. skip

  丢弃前n个元素,返回流。

  

System.out.println("-----------------------");

 

  list.stream().skip(6).forEach(System.out::println);

  System.out.println("-----------------------");

  list.stream().skip(8).forEach(System.out::println);

  -----------------------

  -----------------------

  

 

  7. peek

  接收一个Consumer,对元素做某些操作,但是并不会修改数据(对象数据可能会被修改)。一般用于debug

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  list.stream().peek(System.out::print).count(); // 810975

  

 

  8. sorted

  将流中的元素按自然顺序排序。可以自定义比较器。

  

System.out.println("升序: ");

 

  List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

  list.stream().sorted().forEach(System.out::print);

  System.out.println();

  System.out.println("降序: ");

  list.stream().sorted((x, y) - y - x).forEach(System.out::print);

  015789

  987510

  

 

  五、终点操作

  1. Match

  有allMatch(Predicate p)、anyMatch(Predicate p)、noneMatch(Predicate p)三种方法。

  返回boolean。

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  // allMatch 是否全部符合

  System.out.println(list.stream().allMatch(x - x -1)); // true

  System.out.println(list.stream().allMatch(x - x 1)); // false

  // anyMatch 是否至少有一个符合

  System.out.println(list.stream().anyMatch(x - x == -1)); // false

  System.out.println(list.stream().anyMatch(x - x == 1)); // true

  // noneMatch 是否全部不符合

  System.out.println(list.stream().noneMatch(x - x 5)); // false

  System.out.println(list.stream().noneMatch(x - x 9)); // true

  

 

  2. count

  返回流中元素的数量。返回long

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  System.out.println(list.stream().count()); // 6

  

 

  3. collect

  传入Collectors中的接口实现,将流转化为其他形式的数据。部分接口:

  toList、toSet 转化为list或set

  counting 计数

  reducing 化简

  maxBy、minBy 最大值最小值

  summingInt 求和

  joining 字符串连接

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  // 转化为list格式

  List Integer res1 = list.stream().collect(Collectors.toList());

  // 转化为set格式

  Set Integer res2 = list.stream().collect(Collectors.toSet());

  

 

  4. find

  有findFirst()和findAny()两种。返回Optional对象

  

Optional T findFirst();

 

  

 

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  Optional Integer integer = list.stream().findFirst();

  System.out.println(integer.get()); // 8

  // findAny()对于串行流:一般返回第一个结果

  integer = list.stream().findAny();

  System.out.println(integer.get()); // 8

  // findAny()对于并行流,多次执行会随机返回结果

  integer = list.parallelStream().findAny();

  System.out.println(integer.get()); // 随机打印

  

 

  5. forEach

  遍历流中元素,执行指定操作

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  List Integer res = new ArrayList ();

  list.stream().forEach(e - res.add(e + 2));

  System.out.println(list.toString());

  // [10, 3, 2, 11, 9, 7]

  

 

  6. max、min

  最大值、最小值。返回Optional对象

  将元素按比较器排序,然后min返回第一个数,max返回最后一个数

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  // 升序排序 015789

  System.out.println(list.stream().min((x, y) - x - y).get()); // 0

  System.out.println(list.stream().max((x, y) - x - y).get()); // 9

  // 降序排序 987510

  System.out.println(list.stream().min((x, y) - y - x).get()); // 9

  System.out.println(list.stream().max((x, y) - y - x).get()); // 0

  

 

  7. reduce

  将元素数据结合后返回。

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  // 默认返回Optional类型数据

  Optional Integer res1 = list.stream().reduce(Integer::sum);

  System.out.println(res1.get());

  // 指定返回数据类型为Integer

  Integer res2 = list.stream().reduce(0, Integer::sum);

  System.out.println(res2);

  

 

  8. toArray()

  将流中的元素保存到数组中

  

 A A[] toArray(IntFunction A[] generator);

 

  

 

  

List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);

 

  Integer[] ints = list.stream().map(e - e + 1).toArray(Integer[]::new);

  for (Integer integer : ints) {

   System.out.println(integer);

  

 

  六、参考文档

  https://colobu.com/2016/03/02/Java-Stream/

  https://juejin.cn/post/6844903646648336397#heading-9

  以上就是【java8】stream学习笔记()的详细内容,想要了解更多 【java8】stream学习笔记的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: