Stream的简单使用

Stream的简单使用

一、简述

Java8的新特性,stream(流)是一个来自数据源的元素队列并支持聚合操作,就是将多个操作流程串联成一个管道,通过这个管道对其中的数据进行筛选,排序,聚合等操作,最终输出我们需要的过程,简化了操作流程。stream

特点:1.不是数据结构,不会保存数据。

​ 2.不会修改原来的数据,将操作后的数据保存到另外的一个对象中。

​ 3.延迟执行,在中间处理过程中只是进行记录,不会立即执行,只有等到执行终止操作的时候才会进行计算。

二、分类

中间操作就像水管的一部分,终端就像水龙头,增加水管长度不会消耗水,只有打开了水龙头才会消耗水

操作分类:中间状态(无状态、有状态),终结操作(短路、非短路)

无状态:指元素的处理不受之前元素的影响。(如map或者filter会从输入流中获取每一个元素,并且在输出流中得到一个结果,这些操作没有内部状态)

有状态:指该操作只有拿到所有元素之后才能继续下去。(1.像reduce、sum、max这些操作都需要内部状态来累计计算结果 2.像sort、distinct、limit、skip他们在接受一个流,再生成一个流,但是在排序和去重项需要知道先前的历史,这些操作也是有状态操作的。)

流是否有状态的判断标准,就是看是否需要知道先前的数据历史,前后数据是否有依赖关系来判断

短路:指遇到某些符合条件的元素就可以得到最终结果。

非短路:指必须处理完所有元素才能得到最终结果。(如A||B,只要A为true,则无需判断B的结果)

对于有无状态可能会想到编程里的也有无状态(编程里有状态就是有数据存储功能,线程不安全,无状态就是一次操作,不能保存数据。线程安全),spring中的有无状态等。

三、用法

1.生成stream流的方式

1.Collection体系集合

使用默认方式stream()生成流,default Stream stream()

       List<String> list = new ArrayList<>();
       list.add("abc");
       list.add("def");
       list.add("feg");
       Stream<String> lists = list.stream(); //获取一个顺序流
       Stream<String> listp = list.parallelStream();//  获取一个并行流
       System.out.println(lists.collect(Collectors.joining(",")));
       System.out.println(listp.collect(Collectors.joining(",")));

       Set<String> set = new HashSet<>();
       Stream<String> sets = set.stream();

看了这个案例,就想知道什么是顺序流和并行流吧,安排

 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
 Fork-Join框架:是Java7提供的一个用于执行任务的框架,就是在必要的情况下,将一个大任务,进行拆分(Fork)成若干个小任务(拆分到不能再拆分),再将一个个的小任务运算的结果进行Join汇总(采用“工作窃取”模式) 。
 提问:FORK/JOIN 框架与传统线程池的区别?
     传统线程池在执行任务的时候,如果一个线程在执行过程中由于某些原因无法继续运行,那么该线程就处于等待状态,而在fork/join框架中,如果在该线程中发生阻塞,后面的任务会被其他空闲的线程来进行执行,减少了等待时间,提高了性能。
 
//拆分任务
public class ParallelFlow extends RecursiveTask<Long> {

    private long start;
    private long end;
    private static final long THRESHOLD = 10000;//阈值0

    public ParallelFlow(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long length = end - start;
        //如果不到临界值就执行加操作
        if(length <= THRESHOLD){
            long sum = 0;
            for (long i = start; i < end ; i++) {
                sum += i;
            }
            return sum;
        }else{
            long middle = (start+end)/2;
            ParallelFlow left = new ParallelFlow(start,end);
            left.fork();//拆分子任务,同时压入线程队列
            ParallelFlow right = new ParallelFlow(middle+1,end);
            right.fork();
            return left.join()+right.join();
        }
    }
}


//测试类
public class StreamTest {

    public static void main(String[] args) {
        new StreamTest().fun1();//fork/join框架耗时
        fun2();//for循环耗时
        stramfun1();//串行耗时
        stramfun2();//并行耗时

    }

    //Fork/Join框架
    public void fun1(){
        Instant start = Instant.now();
        ForkJoinPool pool = new ForkJoinPool();
        ParallelFlow task = new ParallelFlow(0,10000L);
        Long sum = pool.invoke(task);
        System.out.println(sum);
        Instant end = Instant.now();
        System.out.println("Fork/Join框架耗时为:"+Duration.between(start,end).toMillis());

    }

    //普通for循环
    public static void fun2(){
        Instant start = Instant.now();
        long sum = 0L;
        for(long i = 0 ; i < 10000L ; i++){
            sum += i;
        }
        System.out.println(sum);
        Instant end = Instant.now();
        System.out.println("for循环耗时为:"+Duration.between(start,end).toMillis());
    }

    //串行流
    public static void stramfun1(){
        Instant start = Instant.now();
        LongStream.rangeClosed(0,10000L).parallel().reduce(0,Long::sum);
        Instant end = Instant.now();
        System.out.println("stream串行流耗时时间:"+ Duration.between(start,end).toMillis());
    }

    //并行流
    public static void stramfun2(){
        Instant start = Instant.now();
        LongStream.rangeClosed(0,10000L).sequential().reduce(0,Long::sum);
        Instant end = Instant.now();
        System.out.println("stream并行流耗时:"+Duration.between(start,end).toMillis());
    }
}

//结果
49995000
Fork/Join框架耗时为:0
49995000
for循环耗时为:0
stream串行流耗时时间:80
stream并行流耗时:0
     
2.Map体系集合

把map转成set集合,间接的生成流

       Map<Integer,String> map = new HashMap<>();
       map.put(1,"第一");
       map.put(2,"第二");
       map.put(3,"第三");
       Stream<Integer> keystream = map.keySet().stream();
       Stream<String> valuestream = map.values().stream();
       Stream<Map.Entry<Integer,String>> entryStream = map.entrySet().stream();
3.数组
      String[] str = {"one","two","three"};
      Stream<String> s1 = Stream.of(str);
      System.out.println(s1.collect(Collectors.joining(",")));

2.中间操作

1.有状态

去重distinct

       List<String> list = Arrays.asList("ma","zhi","chu","zhi","shuo","ma");
       list = list.stream().distinct().collect(Collectors.toList());
       System.out.println(list);
//结果:[ma, zhi, chu, shuo]

跳过skip

        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
        list.stream().skip(4).forEach(System.out::print);
//结果:56789

截断limit

List<String> words = Arrays.asList("one","two","three","four","five");
List<String> limitword = words.stream().limit(3).collect(Collectors.toList());
System.out.println(limitword);
//结果:[one, two, three]

排序sorted

List<Integer> nums = Arrays.asList(1,3,5,6,8,2);
List<Integer> sortedNum = nums.stream().sorted().collect(Collectors.toList());
System.out.println("自然排序:"+sortedNum);
List<Integer> descNum = nums.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println("降序排序:"+descNum);
//结果:自然排序:[1, 2, 3, 5, 6, 8]
//     降序排序:[8, 6, 5, 3, 2, 1]
2.无状态

过滤filter

List<Integer> nums = Arrays.asList(1,3,5,6,8,2);
List<Integer> filterNum = nums.stream().filter(n -> n>5).collect(Collectors.toList());
System.out.println(filterNum);
//结果:[6, 8]

映射map

List<String> list1 = Arrays.asList("one","two","three");
List<String> list2 = list1.stream().map(n -> n.toUpperCase()).collect(Collectors.toList());
System.out.println("转换成大写:"+list2);
List<Integer> list3 = list2.stream().map(n -> n.hashCode()).collect(Collectors.toList());
System.out.println("转换成hash值:"+list3);
//结果:转换成大写:[ONE, TWO, THREE]
//      转换成hash值:[78406, 83500, 79801726]

扁平化flatMap

        List<Integer> num1 = Arrays.asList(1,2,3);
        List<Integer> num2 = Arrays.asList(4,5,6);
        List<Integer> num3 = Arrays.asList(7,8,9);
        List<List<Integer>> lists = Arrays.asList(num1,num2,num3);
        Stream<Integer> outputStream = lists.stream().flatMap(n -> n.stream());
        List<Integer> flatMapResult = outputStream.sorted().collect(Collectors.toList());
        System.out.println(flatMapResult);
//结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]

遍历peek

       String[] arr = new String[]{"a","b","c","d"};
       Arrays.stream(arr).peek(System.out::print).count();
//结果:abcd

3.终端操作

1.短路

匹配所有allMatch

        List<Integer> ins = Arrays.asList(1,2,3,4,5);
        boolean a = ins.stream().allMatch(n -> n>3);
        boolean b = ins.stream().allMatch(n -> n>6);
        System.out.println("a:"+a+" b:"+b);
//结果:a:false b:false
//allMatch表示stream中所有元素都满足条件为true,否则false

任意匹配anyMatch

        List<Integer> ins = Arrays.asList(1,2,3,4,5);
        boolean a = ins.stream().allMatch(n -> n>3);
        boolean b = ins.stream().allMatch(n -> n>6);
        System.out.println("a:"+a+" b:"+b);
//结果:a:true b:false
//allMatch表示stream中所有元素有一个满足条件为true,否则false

不匹配noneMatch

        List<Integer> ins = Arrays.asList(1,2,3,4,5);
        boolean a = ins.stream().noneMatch(n -> n>3);
        boolean b = ins.stream().noneMatch(n -> n>6);
        System.out.println("a:"+a+" b:"+b);
//结果:a:false b:true
//allMatch表示stream中所有元素都不满足条件为true,否则false

查找首个findFirst

        List<Integer> integers = Arrays.asList(2, 2, 3);
        Optional<Integer> first = integers.stream().findFirst();
        System.out.println(first);
        System.out.println(first.isPresent());// 判断是否不等于null,isPresent()相当于!=null的判断
//结果:Optional[2]
//     true
//如果流为空,返回一个空的Optional
2.非短路

遍历forEach

Stream.of(1,2,3,4,5,6).forEach(System.out::print);
//结果:123456

归约reduce

String reduceStr1 = Stream.of("ma", "zhi", "chu").reduce("", String::concat);
//结果:mazhichu

最大值max

List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer maxNum = num.stream().max(Integer::compareTo).get();
System.out.println(maxNum);
//结果:6

最小值min

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer minNum = nums.stream().min(Integer::compareTo).get();
System.out.println(maxNum);
//结果:1

聚合collect

List<Integer> skipNum = IntStream.range(1,100).skip(90).boxed().collect(Collectors.toList());
System.out.println(skipNum);
//结果:[91, 92, 93, 94, 95, 96, 97, 98, 99]

计数count

List<Integer> ls = Arrays.asList(1,2,3,4,5);
long count = ls.stream().count();
System.out.println(count);
//结果:5

;
//结果:1


**聚合collect**

```java
List<Integer> skipNum = IntStream.range(1,100).skip(90).boxed().collect(Collectors.toList());
System.out.println(skipNum);
//结果:[91, 92, 93, 94, 95, 96, 97, 98, 99]

计数count

List<Integer> ls = Arrays.asList(1,2,3,4,5);
long count = ls.stream().count();
System.out.println(count);
//结果:5
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值