Stream

前言:
  本文以下面几个部分介绍并使用Stream
一、Stream的介绍:
  Stream是JDK8API的新成员
  特点:
    1.代码简洁:函数式编程
    2.Stream流只能操作一次
    3.Stream方法返回的是新的流
    4.Stream不调用终止方法,中间操作的方法不会执行
二、Stream的创建方式:
 2.1、创建顺序流(串行流):  
  2.1.1、通过java.util.Collection.stream() 方法用集合创建流
      List<Integer> list = Arrays.asList(8, 5, 9, 2, 6, 1);
      // 创建一个顺序流
      Stream<Integer> stream = list.stream();

  2.1.2、使用java.util.Arrays.stream(T[] array) 方法用数组创建流

      int[] array={1,5,9,4,3,7};
      IntStream stream = Arrays.stream(array);

  2.1.3、使用Stream的静态方法:of()、iterate()、generate()

      Stream<Integer> integerStream = Stream.of(2, 1, 5, 9, 7, 3);

      Stream<Integer> limit = Stream.iterate(0, (x) -> x + 3).limit(4);
      // 0 3 6 9
      limit.forEach(System.out::println);

      Stream<Double> limit1 = Stream.generate(Math::random).limit(3);
      limit1.forEach(System.out::println);
      //0.6649934674181066
      //0.6782015668180121
      //0.7160977203222413

2.2、创建并行流:
  2.2.1、创建并行流

      List<Integer> list = Arrays.asList(8, 5, 9, 2, 6, 1);
      // 创建一个并行流
      Stream<Integer> integerStream = list.parallelStream();

   2.2.2、将 顺序流 转变成 并行流,使用parallel方法

Stream<Integer> parallel = Stream.of(2, 1, 5, 9, 7, 3).parallel()

 



三、Stream的操作流程
  使用形如: 集合.stream.中间方法.终止方法;
  使用形如: 集合.stream.中间方法.中间方法....终止方法;
  使用形如: 集合.stream.终止方法;
  
  流程:
    3.1:第一步,把集合转换为stream流
    3.2:第二步,操作stream流,中间操作,终止操作

四、Stream的使用:
中间方法:
  方法名 含义 源码
筛选 filter 用于过滤流中的数据,返回符合过滤条件的数据 Stream<T> filter(Predicate<? super T> predicate);
去重 distinct 去掉流中重复的数据 Stream<T> distinct();
截取 limit 对流中的数据进行截取,只是截取前N个流中的数据 Stream<T> limit(long maxSize);
skip 跳过前几个元素,获取后面流中的数据 Stream<T> skip(long n);
映射 map 将一种类型的流中元素 映射(转换)到另一个类型流;就是对流的类型的转换 <R> Stream<R> map(Function<? super T, ? extends R> mapper);
mapToInt 将流中的Integer数据装换为int类型数据,然后进行后续操作,提到代码效率 IntStream mapToInt(ToIntFunction<? super T> mapper);
mapToLong   LongStream mapToLong(ToLongFunction<? super T> mapper);
mapToDouble   DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
flatMap   <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
flatMapToInt   IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
flatMapToLong   LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
flatMapToDouble   DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
排序 sorted 对数据进行排序;根据元素的自然顺序排序 Stream<T> sorted();
  Stream<T> sorted(Comparator<? super T> comparator);

终止方法:
  方法名 含义 源码
匹配/遍历 anyMatch 匹配某个元素,只要其中一个元素满足条件即可 boolean anyMatch(Predicate<? super T> predicate);
allMatch 匹配所有元素,所有都都需要满足条件 boolean allMatch(Predicate<? super T> predicate);
noneMatch 匹配所有元素,所有元素都不满足条件 boolean noneMatch(Predicate<? super T> predicate);
findAny 返回描述流的某些元素 Optional<T> findAny();
findFirst 寻找流中的第一个元素 Optional<T> findFirst();
forEach 遍历流最终的数据 void forEach(Consumer<? super T> action);
归约 reduce

将流中的数据 进行归纳,最终得到一个数据;适用于数字 T reduce(T identity, BinaryOperator<T> accumulator);
  Optional<T> reduce(BinaryOperator<T> accumulator);
 

<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);

聚合 count 统计流中元素的个数 long count();
max 获取流中的最大值,需要指定排序规则 Optional<T> max(Comparator<? super T> comparator);
min 获取流中的最小值,需要指定排序规则 Optional<T> min(Comparator<? super T> comparator);
收集 collect

最终 将数据收集成指定的类型

 

<R, A> R collect(Collector<? super T, A, R> collector);
   

<R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);

       

























































/**使用普通集合操作数据的弊端:
* 每个需求都需要循环,这样需要一个新的集合来存储最终的数据,操作麻烦
*/

/** 操作Stream注意的3点:
* 1.Stream流只能操作一次
* 2.Stream方法返回的是新的流
* 3.Stream不调用终结方法,中间的操作不会执行。
* 目前终结方法有count、foreach,坦白的讲不返回Stream流即可,一定返回新的类型
*/

//串行的Stream流:在一个线程上运行

/** Stream流的操作方法:
* 1.forEach:遍历流最终的数据;
* 使用lambda表达式
* lambda表达式可以转成方法引用 A :: a
*
* 2.count:统计流中元素的个数
*
* 3.filter:用于过滤流中的数据,返回符合过滤条件的数据
*
* 4.limit:对流中的数据进行截取,只是截取前N个流中的数据
*
* 5.skip:跳过前几个元素,获取后面流中的数据
*
* 6.map:将一种类型的流中元素 映射(转换)到另一个类型流;就是对流的类型的转换
*
* 7.sorted:对数据进行排序;根据元素的自然顺序排序
*
* 8.distinct:去掉流中重复的数据
*
* 9.Match:判断流中的数据 是否与指定的条件 匹配
* allMatch:匹配所有元素,所有都都需要满足条件
* anyMatch:匹配某个元素,只要其中一个元素满足条件即可
* noneMatch:匹配所有元素,所有元素都不满足条件
*
* 10.find:找某些元素
* findFist:寻找流中的第一个元素
* findAny:寻找流中的第一个元素
*
* 11.max 和 min
* max: 获取流中的最大值,需要指定排序规则
* min: 获取流中的最小值
*
* 12.reduce:将流中的数据 进行归纳,最终得到一个数据;适用于数字
* 例如:求和
* identity,lambda表达式
*
* 13.map 和 reduce 组合使用:
* 先试用map进行数据类型的装换,在使用reduce 对数进行归纳
*
* 将包装类 转化 基本数据类型
* 14.mapToInt:将流中的Integer数据装换为int类型数据,然后进行后续操作,提到代码效率
* Integer占用的内存比Int多,在Stream流中操作会进行自动的装箱与拆箱,
* 为了提高代码的效率,我们先将流中的Integer转换为int数据,然后再操作
*
* mapToXXX:
*
* 15.concat:将2个流合并成1个流,这是个静态方法
* 注意:这两个流类型相同
* Stream.concat(流1,流2)
*
* 16.collect:最终 将数据收集成指定的类型
* Collectors.toList();
* Collectors.toSet();
* Collectors.toCollection( () -> new ArrayList<>() );
* => Collectors.toCollection( ArrayList::new );
* Collectors.toCollection( () -> new HashSet<>() );
*
* 聚合计算:
* 获取最大值:Collectors.maxBy( (a,b)->a.getXXX - b.getXXX)
* 获取最小值:Collectors.minBy( (a,b)->a.getXXX - b.getXXX )
* 求和: Collectors.summingXXX(a->a.getXXX)
* 平均值: Collectors.averagingXXX(a::getXXX)
* 统计数量: Collectors.counting()
*
* 分组:以某个条件进行分组
* 1. Collectors.groupingBy(对象::get属性)
* 结果:Map<get属性,List<对象>>
* k:get属性 v:List<对象>
* 2. Collectors.groupingBy( a->{return a.getXXX > 条件 ? "值1" : "值2"})
*
* 分区:把集合中的数据分隔成2个列表,一个true列表,一个false列表
* Collectors.partitoningBy(分区条件);
*
* 拼接:根据指定的连接符,将所有的元素连接成一个字符串
* Collectors.joining("分隔符","前缀","后缀")
*
*/


//并行的Stream流:多线程处理
/**
* 创建方式:
* 1. 集合名.parallelStream()
* 2. Stream.of(1,2,3).parallel();
*
* 线程安全问题:
* 加同步锁:Synchronized(){ }
*
*
*
*/
 
posted @ 2022-08-24 22:27  向大海  阅读(468)  评论(0编辑  收藏  举报