首页 > 技术文章 > Java的Stream表达式

yangfei629 2019-08-29 00:00 原文

1、如何理解Stream


Java8新特性

Stream可以理解为管道,管道里的流水就是数据,管道里可以对水进行处理,如过滤,消毒,净化等等操作。最后流出的水才能喝。

所以我理解Stream关注的是对数据的加工计算。对比java集合框架,集合框架关注的是如何存取数据。

一个stream操作主要有3个部分:源头、中间操作、终止操作。

中间操作可以有0个或多个 但不是立马执行的,只有终止操作被调用后中间操作才会一起执行(惰性执行)

有了stream操作后 会简化我们的操作,如循环

如循环一个数组,打印,如下操作,而非原来的for循环,是否很简洁

int[] intArray = new int[]{2,4,6,1};
Arrays.stream(intArray).forEach(System.out::println);

  

2、Stream来源


 

 stream主要来源:数组 集合 

数组:

int[] intArray = new int[]{2,4,6,1};
Arrays.stream(intArray).forEach(System.out::println);
Stream.of(intArray).forEach(System.out::println);

 

 

集合Collection

 

strList.stream().forEach(System.out::println);
Stream.of(strList).forEach(System.out::println);

  

3、中间操作


 主要有filter map flatmap sorted skip limit distinct

例:

public static void main(String[] args) {
        List<String> strList = Arrays.asList("yy","ff","dd","11","12","##");
        strList.stream().filter(x->x.matches("^\\w.*")).
                map(x->x+"end").sorted().skip(1).limit(2).distinct().forEach(System.out::println);
    }

输出:

12end
ddend

  

 主要说明下flatmap 这个是把流的每个元素映射为一个stream ,再把所有的stream连到一起(扁平化操作),例:

strList.stream().flatMap(x->Stream.of(x.split(","))).forEach(System.out::println);

 

每次中间操作都会产生一个新的stream  

 

4、终止操作


主要有:

reduce,foreach,collect

allMatch,anyMatch,noneMatch

findFirst,findAny

max,min,count

 例:

import java.util.*;
import java.util.stream.Collectors;

class StreamMode{
    private String name;
    private int age;

    public StreamMode(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "StreamMode{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class StreamYf {
    public static void main(String[] args) {
        List<StreamMode> strList = new ArrayList<>();
        StreamMode streamMode1 = new StreamMode("y1",21);
        StreamMode streamMode2 = new StreamMode("y3",22);
        StreamMode streamMode3 = new StreamMode("y2",23);
        StreamMode streamMode4 = new StreamMode("y4",20);
        StreamMode streamMode5 = new StreamMode("y5",19);

        strList.add(streamMode1);
        strList.add(streamMode2);
        strList.add(streamMode3);
        strList.add(streamMode4);
        strList.add(streamMode5);

        //map reduce(lamdba需要两个参数)
        Optional<Integer> reduce = strList.stream().map(StreamMode::getAge).reduce(Integer::sum);
        System.out.println(reduce.get());

        //allMatch 全部匹配 (anyMatch noneMatch用法一样)
        boolean resultAllMatch = strList.stream().allMatch(x -> x.getAge() > 20);
        System.out.println("resultAllMatch="+resultAllMatch);

        //findFirst找出排序后的第一个元素(降序即从大到小)
        Optional<StreamMode> firstEle = strList.stream().sorted(Comparator.comparingInt(StreamMode::getAge).reversed()).findFirst();
        System.out.println("firstEle="+firstEle.get());

        //findAny找出任一个元素
        Optional<StreamMode> anyEle = strList.stream().findAny();
        System.out.println("anyEle="+anyEle.get());

        //找出最大的元素 min类似
        Optional<Integer> maxAge = strList.stream().map(StreamMode::getAge).max(Integer::max);
        System.out.println("maxAge="+maxAge.get());

        //统计过滤后元素的个数
        long count = strList.stream().filter(x -> x.getAge() > 20).count();
        System.out.println("count="+count);

        //collect 收集后转为List toSet类似用法
        List<Integer> collectList = strList.stream().map(StreamMode::getAge).collect(Collectors.toList());
        System.out.println("collectList="+collectList);

        //collect 收集后转为Map
        Map<String, List<StreamMode>> collectMap = strList.stream().collect(Collectors.groupingBy(StreamMode::getName));
        System.out.println("collectMap="+collectMap);

        //collect 收集后求平均年龄 sum max 类似
        Double collectAvg = strList.stream().collect(Collectors.averagingInt(StreamMode::getAge));
        System.out.println("collectAvg="+collectAvg);
        //collect 获取SummaryStatistics 可以一次性获取max min sum等
        IntSummaryStatistics collectAll = strList.stream().collect(Collectors.summarizingInt(StreamMode::getAge));
        System.out.println("collectAvg2="+collectAll.getAverage());
        System.out.println("collectCount2="+collectAll.getCount());
    }
}

 

5、并发stream


paralleStream基于ForkJoin(把大任务拆为多个子任务计算再合并)可以实现并行stream

并非线程安全 慎用

推荐阅读