zoukankan      html  css  js  c++  java
  • Java--Stream流操作

    Java--Stream流操作

    一、Stream概述

    Jdk在1.7之后提供了函数式编程,随之而来的还有Stream流。

    通过流可以达成链式操作。

    Stream这里的流与IO流毫无关系,这里的流指的是流式操作,就是流水线操作。

    Stream流操作主要包包括三大模块:创建流操作、中间流操作、终结流操作。

    其中创建流主要是创建Stream对象。每个Stream对象只能使用一次终结操作。

    中间流操作指的是各种中间流操作方法,比如去重、过滤、排序等

    终结流操作指的结果操作,终结操作的目的是产生最终结果。

    二、创建流

    Java提供了多种方式创建流。

    1、基于数组创建流

    Arrays有个静态方法stream可以将数组转换成对应的Stream.

    Stream的of方法也是调用它。

    	int[] a = new int[] { 1, 2, 3, 4 };
    
         IntStream s = Arrays.stream(a);//方法一
    
         
    	Stream<String> s2=Stream.of("h","e","l","l","o");//方法二
    
    	s.forEach(System.out::print);//遍历输出
    	s2.forEach(System.out::print);
    

    2、基于生成器创建流

    Stream提供了生成器方法,可用于构建流。

    	Builder builder= Stream.builder();
    
        Stream<String> stream= builder.add("hello").add("world").build();
    
        stream.forEach(System.out::println);
    

    3、基于集合创建流

    集合和数组一样,也可以创建流。

     List<Integer> list=new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
          
            Stream<Integer> stream=list.stream();
            stream.forEach(System.out::println);
    

    4、基于函数创建流

    Stream的generate方法接收一个Supplier参数,即一个有返回值的函数,同时通过limit函数控制生成次数。

    Stream<String> stream=Stream.generate(()->"hello world").limit(10);//生成10次
            stream.forEach(System.out::println);//打印10次hello world
    

    二、中间流

    这里的流中间操作指的是该操作的返回值仍然是流。

    并且中间流操作需要有终结流结尾。

    流操作函数如下:

    序号 操作 方法 说明 备注
    1 filter Streamfilter(Predicate<?superT>predicate) 返回当前流中满足参数predicate过滤条件的元素组成的新流 过滤器
    2 map Streammap(Function<?superT,?extendsR>mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新流 函数
    3 mapToInt IntStreammapToInt(ToIntFunction<?superT>mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Int流 函数
    4 mapToLong LongStreammapToLong(ToLongFunction<?superT>mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Long流 函数
    5 mapToDouble DoubleStreammapToDouble(ToDoubleFunction<?superT>mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Double流 函数
    6 flatMap StreamflatMap(Function<?superT,?extendsStream<?extendsR>>mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的流来返回 扁平函数
    7 flatMapToInt IntStreamflatMapToInt(Function<?superT,?extendsIntStream>mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的Int流来返回 扁平函数
    8 flatMapToLong LongStreamflatMapToLong(Function<?superT,?extendsLongStream>mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的Long流来返回 扁平函数
    9 flatMapToDouble DoubleStreamflatMapToDouble(Function<?superT,?extendsDoubleStream>mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的Double流来返回 扁平函数
    10 distinct Streamdistinct() 返回去掉当前流中重复元素之后的新流 去重
    11 sorted Streamsorted() 返回当前流中元素排序之后的新流,需要元素类型实现Comparable 排序
    12 sorted Streamsorted(Comparator<?superT>comparator) 返回当前流中元素排序之后的新流,需要传递一个Comparator 排序
    13 peek Streampeek(Consumer<?superT>action) 针对流中的每个元素执行操作action 查阅
    14 limit Streamlimit(longmaxSize) 返回指定的数量的元素组成的新流 限制
    15 skip Streamskip(longn) 返回第n个之后的元素组成的新流 跳过

    这些函数用法一样,只是参数和返回值方面有些差异。有些函数其实功能完全 一样,只是名字不同而已,方便区分罢了。

    1、filter过滤

    filter方法是过滤器方法,针对的是流中所有元素,满足条件的元素将会被保留以组成新的流。

     //过滤流
        static void filter_o(List<Integer> list){
           Stream<Integer> stream= list.stream();
    
           stream.filter(e->e>3).peek(System.out::println).count();
            //peek(System.out::println).count()==forEach(System.out::println)
        }
    
        // Stream流操作
        public static void main(String[] args) {
    
    
            List<Integer> list=new ArrayList<>();
            list.add(1);
            list.add(3);
            list.add(5);
            list.add(7);
    
            filter_o(list);
          
    
        }
    

    2、peek查阅

    peek对流中的每个元素执行一次操作,类似forEach,不过forEach是终结流,peek是中间流。

    以上的语句中也可以这样写:

    stream.filter(e->e>3).peek(e->System.out.println(e)).count();
    

    通常用于查阅。

    3、map映射

    map映射函数,用于处理元素。

    map方法的参数类型为Function,该函数式接口用于接受一个参数,返回一个结果。

    使用同上。

    4、distinct去重

    distinct方法用于去重

    5、limit截取

    取到前n个元素

    6、sorted排序

    对元素排序

    。。。。。。。。。

    三、终结流

    使用终结流之后该流接结束了,不会再返回流。

    常用的方法有:

    1、forEach循环

    接收一个函数,对每个元素执行一次函数,常用于遍历。

    2、count计数

    返回流中元素的个数。

    3、max/min最值

    通过给定规则,返回最值。

    4、collect归纳

    collect用于归纳总结,并返回相应数据集合。

    该方法有两个,一个接收三个函数作为参数,一个接收一个collector.

     public interface Stream<T> extends BaseStream<T, Stream<T>> {
         
            <R> R collect(Supplier<R> supplier,
                          BiConsumer<R, ? super T> accumulator,
                          BiConsumer<R, R> combiner);
         
            <R, A> R collect(Collector<? super T, A, R> collector);
        }
    

    、第一个重载方法,三个参数分别是三个函数,直接使用函数引用即可。

    List<Integer> list1=stream.filter(e->e>3)
        .peek(e>System.out.println(e))
        .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    
    //参数1创建一个集合,参数2指定加入元素的方法,参数3用于并行流
    //使用方法引用,也可以使用lambda,如:
    ()->{ArrayList l=new ArrayList<>();return l;},
    (l,e)->{l.add(e);},
    (l,e)->{l.addAll(e);}
    
    

    第二个重载方法,需要传入一个Collector类型的参数,这个Collector是定义来承载一个收集器,但是JDK提供了一个Collectors工具类,可以将流中的元素转换成各种容器。

    如:

    List<Integer> list1=stream.filter(e->e>3).peek(e->System.out.println(e))
          .collect(Collectors.toList());
    
  • 相关阅读:
    [BZOJ3172]单词
    [BZOJ2434]阿狸的打字机
    [BZOJ1195]最短母串
    [codeforces743E]Vladik and cards
    [BZOJ2553]禁忌
    [BZOJ1009]GT考试
    [BZOJ3507]通配符匹配
    [BZOJ4027]兔子与樱花
    test20190308
    Luogu P2742 模板-二维凸包
  • 原文地址:https://www.cnblogs.com/cgl-dong/p/12199485.html
Copyright © 2011-2022 走看看