JAVA8新特性学习记录(二) Stream 流

Stream 流

是数据渠道,用于操作数据源(集合,数组)等所生成的元素序列。
① Stream 自己不会存储元素。
② Stream 不会改变源对象。会返回一个持有结果的新Stream.
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

一、Stream的三个操作步骤:

  • 1.创建Stream的几种方式

        //1.可以通过Collection系列集合提供的Stream() 或 parallelStream()
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();

        //2.通过Arrays 中的静态方法 stream() 获取数组流
        String[] str = new String[10];
        Stream<String> stream1 = Arrays.stream(str);

        //3.通过Stream类中的静态方法 of
        Stream<String> stream2 = Stream.of("aa", "bb", "cc");

        //4.创建无线流
        //迭代
        Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
        //生成
        Stream.generate(() -> new Random().nextInt());
  • 2.中间操作

–筛选与切片

        /*
         * 筛选与切片
         * filter -- 接收Lambda,从流中排除某些元素
         * limit -- 截断流,使其元素不超过指定数量
         * skip(n) --跳过元素,返回一个跳过了前 n 个元素的流。若流中元素不足n个,则返回一个空流,与limit互补
         * distinct -- 筛选,通过流所生成的  hashCode 和 equals() 去重
         *
         * */
        List<String> lists = Arrays.asList(("123"),
                ("456"),
                ("789"),
                ("123"),
                ("456"));

        //过滤掉长度不大于2的,限制4个,也就是把第二个456去掉了。跳过2个,就是789,123
        lists.stream()
                .filter((x) -> x.length() > 2)
                .limit(4)
                .skip(2)
                .forEach(System.out::println);

        //全部去重,123,456,789
        lists.stream().distinct().forEach(System.out::println);

–映射

public static void main(String[] args) {

        /**
         * 映射
         * map--接收lambda,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新元素
         *
         */
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map((str) -> str.toUpperCase()).forEach(System.out::println);
        /**
         * flatMap --接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
         * */
        //流中流
        Stream<Stream<Character>> stream = list.stream().map(
                TestStreamAPI2::filterChartater
        );
        stream.forEach((sm) -> sm.forEach(System.out::println));

        //使用flatMap
        Stream<Character> streams = list.stream().flatMap(TestStreamAPI2::filterChartater);
        streams.forEach(System.out::println);

    }

    static Stream<Character> filterChartater(String str) {
        List<Character> lists = new ArrayList<>();

        for (Character c : str.toCharArray()) {
            lists.add(c);
        }
        return lists.stream();
    }

–排序

        //排序
        //自然排序: sorted()
        List<String> list = Arrays.asList("ddd", "bbb", "aaa", "ccc");
        list.stream().sorted().forEach(System.out::println);

        //定制排序:  sorted(Comparator com)
        list.stream().sorted(
                (e1,e2)->{
                    int i = e2.compareTo(e1);
                    return i;
                }
        ).forEach(System.out::println);
  • 3.终止操作

–查找与匹配

        /**
         * 查找与匹配
         *
         * allMatch --检查是否匹配所有元素
         * anyMatch --任意一个
         * noneMatch --没有匹配
         *
         * */

        boolean allMatch = list.stream().allMatch((x) -> x.equals("aaa"));
        boolean anyMatch = list.stream().anyMatch((x) -> x.equals("aaa"));
        boolean noneMatch = list.stream().noneMatch((x) -> x.equals("aaa"));
        System.out.println(allMatch + "," + anyMatch + "," + noneMatch);

		/*
		 * findFirst --返回第一个元素
         * findAny --返回当前流中的任意元素.经验证,并不随机。待研究。
		*/
        Optional<String> first = list.stream().findFirst();
        Optional<String> any = list.parallelStream().findAny();
        System.out.println("first:" + first.get() + ",any:" + any.get());

		/*       
		 * count --总个数
         * max--最大值
         * min --最小值
         */
        long count = list.stream().count();
        Optional<String> max = list.stream().max(String::compareTo);
        Optional<String> min = list.stream().min(String::compareTo);
        System.out.println("count:"+count+",max:"+max.get()+",min:"+min.get());

–规约与收集

		List<String> list = Arrays.asList("ddd", "bbb", "aaa", "ccc");
        List<Integer> lists = Arrays.asList(1,2,3,4,5);
        /**
         * 规约
         *
         * reduce(T identity,BinaryOperator)/reduce(BinaryOperator) 
         * --可以将流中元素反复结合起来,得到一个值
         *
         * */

        List<Integer> lists = Arrays.asList(1,2,3,4,5);
        //起始值 为0,即0作为x,1作y,得到的返回值再作x,再加2...
        Integer reduce = lists.stream().reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        
        /**
         * 收集:
         * Collect-将流转换为其他形式,接受一个Collector接口的实现,用于给Stream中元素做汇总的方法
         * */
        List<String> listss = list.stream().collect(Collectors.toList());
        Set<String> sets = list.stream().collect(Collectors.toSet());
        HashSet<String> hashSet = list.stream().collect(Collectors.toCollection(HashSet::new));

        //总数
        Long collect = lists.stream().collect(Collectors.counting());
        //平均
        Double collect2 = lists.stream().collect(Collectors.averagingInt(Integer::intValue));
        //总和
        Integer collect1 = lists.stream().collect(Collectors.summingInt(Integer::intValue));

        System.out.println(collect+","+collect1+","+collect2);
        //最大值
        //最小值
        ......

–功能API还有很多,可以自己尝试。这里不多赘述了。

并行流与顺序流

并行流就是把一个内容分成多个数据块,并有不同的线程分别处理每个数据块的流。
JAVA8 中将并行进行了优化,我们可以很容易的对数据进行操作。StreamAPI 可以声明性的通过
parallel() 与 sequential() 在并行流和顺序流 之间进行切换。

fork join式 并行。拆分合并充分利用cpu

        // 执行时间373
        Instant start = Instant.now();
        long reduce1 = LongStream.rangeClosed(0, 1000000000L)
                .reduce(0, Long::sum);

        Instant end = Instant.now();
        System.out.println(Duration.between(start,end).toMillis());

        //并行 执行时间106
        Instant start2 = Instant.now();
        long reduce2 = LongStream.rangeClosed(0, 1000000000L)
                .parallel()
                .reduce(0, Long::sum);
        Instant end2 = Instant.now();
        System.out.println(Duration.between(start2,end2).toMillis());

        //切换回顺序 3361  
        Instant start3 = Instant.now();
        long reduce3 = LongStream.rangeClosed(0, 1000000000L)
                .sequential()
                .reduce(0, Long::sum);
        Instant end3 = Instant.now();
        System.out.println(Duration.between(start3,end3).toMillis());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值