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());
posted @ 2020-01-16 07:44  cgl_dong  阅读(461)  评论(0编辑  收藏  举报