Java Stream

Java Stream


概述

  • JDK : 1.8

总结

  • 概念定义1
    • Stream 是增强型的 Iterator
    • Stream 是对集合(Collection)对象功能的增强,专注于对集合对象进行便利、高效的聚合操作、大批量数据操作
  • 特点总结:
    • 无存储:Stream不是一种数据结果,只是数据的一种视图
    • 无修改:Stream任何修改都不会影响原来的数据源
    • 无限制:Stream 数据源本身可以是无限大小
    • 一次消费:单向处理,Stream一次遍历后即会失效,再次处理需要再次遍历
    • 堕式执行:Stream上的操作并不会立即执行,而是等到使用结果时才会执行;节省执行时间
    • 可并行化:并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程;并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程
    • 无法索引:不支持通过数组下标访问集合元素的方式
    • 无顺序性:输出结果不保证与原有集合中元素顺序相同
  • 操作类型
    • 中间操作:
      • 一个Stream后跟0或多个中间操作,过滤或排序等操作生成新的Stream
      • 惰性操作:仅仅只是方法调用而并未实际对流进行处理,只有在获取结果时才会执行
    • 最终操作:
      • 一个Stream只有一个最终操作,只有执行到最终操作时才会进行流的处理

操作

  • Stream 构建2

        /**
         * Stream 初始化
         */
        private static void streamInit(){
            // 数值型 Stream
            Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8);
            Stream<Long> longStream = Stream.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L);
            Stream<Float> floatStream = Stream.of(1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f);
    
            // 三种基本数值型提供了对应的Stream
            IntStream intStream = IntStream.of(1,2,3,4,5,6,7,8);
            LongStream longStreams = LongStream.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L);
            DoubleStream doubleStream = DoubleStream.of(1f,2f,3f,4f,5f,6f,7f,8f);
    
            // 字符串
            Stream<String> stringStream = Stream.of("a", "b", "c", "d", "e", "f", "g", "h");
    
            // 数组
            Stream<Integer> integerArrayStream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8);
            Arrays.stream(new int[]{1,2,3,4,5,6});
    
            // 集合
            Stream<List<Integer>> listStream = Stream.of(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));
            
            // 生成器
        	Stream.generate(Math::random);
        }
    
    
        /**
         * Stream 数值型Stream 构造
         */
        private static void streamNumberBuild(){
            // 全部数据
            IntStream.of(1,2,3,4,5).forEach(System.out::print);
          
            // [ )区间
            IntStream.range(1,5).forEach(System.out::print);
           
            // [ ]区间
            IntStream.rangeClosed(1,5).forEach(System.out::print);
    
            // 连接
            IntStream.concat(IntStream.range(1,5),IntStream.rangeClosed(5,10)).forEach(System.out::print);
          
        }
    
    /**
     *  集合工具类中提供默认构造Stream方法
     */
    public interface Collection<E> extends Iterable<E> {
        default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
        }
    }
    
    public class Arrays {
        public static <T> Stream<T> stream(T[] array) {
            return stream(array, 0, array.length);
        }
    }
    
  • Stream map()

        /**
         * Stream map 数据映射,将输入流通过某种规则变更后改为输出流
         *map 将对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素
         *flatMap 对Stream 进行操作
         */
        private static void streamMap(){
    
            // map 转换结果 1对1映射
    
            // 字符串大小写转换
            List<String> strings = Arrays.asList("a", "b", "c");
            strings.stream().map(String::toUpperCase).collect(Collectors.toList()).forEach(System.out::print);
    
            // 数据平方值
            Arrays.asList(1,2,3,4,5).stream().map(n->n*n).collect(Collectors.toList()).forEach(System.out::print);
    
            // map 转换结果 1对多映射
            Stream<List<Integer>> stream = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6 ), Arrays.asList(7, 8, 9));
            stream.flatMap(a -> a.stream()).forEach(System.out::print);
          
        }
    
  • Stream limit()、skip()

        /**
         * Stream
         * limit 只输出前 n 个
         * skip  只过滤前 n 个
         */
        private static void streamLimitAndSkip(){
            Arrays.asList(1,2,3,4,5,6,7,8,9).stream().limit(3).forEach(System.out::print);
            Arrays.asList(1,2,3,4,5,6,7,8,9).stream().skip(3).forEach(System.out::print);
        }
    
  • Stream peek()、forEach()

        /**
         * Stream peek:通过 peek 可以查看多次转换结果
         * peek方法生成一个包含原Stream的所有元素的新Stream
         * Stream forEach: 不改变元素,无法通过break/continue/return终止,只能输出一次
         */
        private static void streamPeek(){
    		Arrays.asList(1,2,3,4,5,6,7,8,9).stream().filter(a -> a > 3).peek(a -> System.out.println("a:"+a))
                    .map(a -> a * a).peek(a -> System.out.print("a:"+a)).collect(Collectors.toList())
                    .forEach(System.out::print);
        }
    
  • Stream optional()

        /**
         * Stream Optional
         */
        private static void streamOptional(){
            String str = null ;
            System.out.println(Optional.ofNullable(str).map(String::length).orElse(-1));
        }
    
  • Stream Iterate()

        private static void streamIterator(){
            Stream.iterate(0,a -> a+2).limit(10).collect(Collectors.toList()).forEach(System.out::print);
        }
    
  • Stream match()

    /**
     * Stream match
     * allMatch 所有全部符合
     * anyMatch 存在符合元素
     * noneMatch 全部不符合
     */
    private static void streamMatch(){
        // 两个集合取交集
        final List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
        boolean b = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8).stream().anyMatch(a -> integerList.contains(a));
        System.out.println(b);
        // Lambda 表达式内部使用的外部参数,引用值而非变量,相当于 final 修饰
        // 当变量重新赋值时会提示便于错误
        // 如果 Lambda 表达式内部使用某个变量的值,而该变量后续需要重新赋值,需要对该值进行拷贝,避免异常
        
        System.out.println(Arrays.asList(1, 3, 5, 7, 9).stream().noneMatch(a -> integerList.contains(a)));
    }
  • Stream collect3
  1. collector.group

        /**
         * Stream group
         */
        private static void streamGroup(){
            // 将数组分为奇数偶数两个集合
            Map<Boolean, List<Integer>> collect = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().collect(Collectors.partitioningBy(a -> a % 2 == 0));
            collect.forEach( (a,b) -> System.out.println("key:"+a+",value:"+b.toString()));
            // 将List转为Map
            List<OrderGoods> orderGoodsList = generateOrderGoodsList();
            Map<String, List<OrderGoods>> orderGoodsGroupMap = orderGoodsList.stream().collect(Collectors.groupingBy
                    (orderGoods -> String.format("%d_%d_%d_%d", orderGoods.getGoodsId(), orderGoods.getGroupGoodsId(), orderGoods.getIsGift(), orderGoods.getSellerId())));
            orderGoodsGroupMap.forEach((a,b) -> System.out.println("key:"+a+",value:"+b.toString()));
        }
    
        private static List<OrderGoods> generateOrderGoodsList(){
            OrderGoods orderGoods1 = new OrderGoods();
            orderGoods1.setGoodsId(1);
            orderGoods1.setGroupGoodsId(1);
            orderGoods1.setIsGift(0);
            orderGoods1.setSellerId(1);
            orderGoods1.setOrderId(1);
    
            OrderGoods orderGoods2 = new OrderGoods();
            orderGoods2.setGoodsId(1);
            orderGoods2.setGroupGoodsId(1);
            orderGoods2.setIsGift(1);
            orderGoods2.setSellerId(1);
            orderGoods2.setOrderId(2);
    
            OrderGoods orderGoods3 = new OrderGoods();
            orderGoods3.setGoodsId(1);
            orderGoods3.setGroupGoodsId(1);
            orderGoods3.setIsGift(0);
            orderGoods3.setSellerId(1);
            orderGoods3.setOrderId(1);
    
            OrderGoods orderGoods4 = new OrderGoods();
            orderGoods4.setGoodsId(1);
            orderGoods4.setGroupGoodsId(1);
            orderGoods4.setIsGift(0);
            orderGoods4.setSellerId(1);
            orderGoods4.setOrderId(2);
    
            OrderGoods orderGoods5 = new OrderGoods();
            orderGoods5.setGoodsId(1);
            orderGoods5.setGroupGoodsId(1);
            orderGoods5.setIsGift(0);
            orderGoods5.setSellerId(1);
            orderGoods5.setOrderId(2);
    
            return Arrays.asList(orderGoods1,orderGoods2,orderGoods3,orderGoods4,orderGoods5);
        }
    
    
    public class OrderGoods {
    
        private Integer orderId ;
    
        private Integer goodsId ;
    
        private Integer groupGoodsId ;
    
        private Integer isGift ;
    
        private Integer sellerId ;
    
        public Integer getOrderId() {
            return orderId;
        }
    
        public void setOrderId(Integer orderId) {
            this.orderId = orderId;
        }
    
        public Integer getGoodsId() {
            return goodsId;
        }
    
        public void setGoodsId(Integer goodsId) {
            this.goodsId = goodsId;
        }
    
        public Integer getGroupGoodsId() {
            return groupGoodsId;
        }
    
        public void setGroupGoodsId(Integer groupGoodsId) {
            this.groupGoodsId = groupGoodsId;
        }
    
        public Integer getIsGift() {
            return isGift;
        }
    
        public void setIsGift(Integer isGift) {
            this.isGift = isGift;
        }
    
        public Integer getSellerId() {
            return sellerId;
        }
    
        public void setSellerId(Integer sellerId) {
            this.sellerId = sellerId;
        }
    
        @Override
        public String toString() {
            return "goodsId:"+goodsId+",groupId:"+groupGoodsId+",isGift:"+isGift+",sellerId:"+sellerId+",orderId:"+orderId;
        }
    }
    
  2. collectors 集合

        /**
         * Stream collect 集合常用操作
         */
        private static void streamCollectOperation(){
            // 平均值
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().collect(Collectors.averagingInt(value -> value)));
            // 最大值
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().collect(Collectors.maxBy(Comparator.comparingInt(o -> o))).orElse(1));
            // 最小值
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().collect(Collectors.minBy(Comparator.comparingInt(a -> a))).orElse(1));
            // 统计
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().collect(Collectors.counting()));
            // 求和
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().collect(Collectors.summarizingInt(a -> a)));
        }
    
    
  3. collectors 集合分组

    /**
     * Stream collect 集合分组
     */
    private static void streamCollectGroup(){
        // 集合分组
        Arrays.asList(1,2,3,4,5).stream().collect(Collectors.partitioningBy(a -> a % 2 == 0)).forEach((a,b) -> System.out.println("a:"+a+",b:"+b));
        Arrays.asList(1,2,3,4,5).stream().collect(Collectors.groupingBy(a -> a %2 ==0)).forEach((a,b) -> System.out.println("a:"+a+",b:"+b));
        // 分组计数
        Arrays.asList(1,2,3,4,5).stream().collect(Collectors.partitioningBy( a -> a % 2 == 0 ,Collectors.counting())).forEach((a,b) -> System.out.println("a:"+a+",b:"+b));
    }
    
  4. collectors.joining4

        private static void streamCollectorJoining(){
            // 第一个参数:分割符号
            // 第二个参数:前缀符号
            // 第三个参数:后缀符号
            System.out.println(Arrays.asList("1", "2", "3", "4", "5").stream().collect(Collectors.joining(",", "[", "]")).toString());
        }
    
  • Stream reduce()5

        /**
         * Stream reduce
         * 1.第一个参数:起始数据
         * 2.第二个参数:函数方法
         */
        private static void streamRuduce(){
            // 字符串拼接
            System.out.println(Stream.of("a", "b", "c", "d").reduce("", String::concat));
            // 求最小数值
            System.out.println(Stream.of(1.0, 2.0, 3.0, -1.0, -2.0).reduce(0.0, Double::min));
            // 数组值求和
            System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).reduce(0, Integer::sum));
        }
    
    
        private static void streamCollectorReduce(){
            // 第一个参数:中间运算结果
            // 第二个参数:集合中的元素
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().reduce((a, b) -> a += b).orElse(0));
            // 第一个参数:初始参数数值
            // 第二个参数:中间运算结果
            // 第三个参数:集合中的元素
            System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().reduce(0, (a, b) -> a += b).intValue());
    
            ArrayList<Integer> reduce = Arrays.asList(1, 2, 3, 4, 5).stream().reduce(new ArrayList<>(), (integers, integer) -> {
                integers.add(integer);
                return integers;
            }, (integers, integers2) -> {
                integers.addAll(integers2);
                return integers;
            });
            System.out.println(reduce.stream().collect(Collectors.summarizingInt(a -> a)));
        }
    
        private static void streamCollectorJoining(){
            // 第一个参数:分割符号
            // 第二个参数:前缀符号
            // 第三个参数:后缀符号
            System.out.println(Arrays.asList("1", "2", "3", "4", "5").stream().collect(Collectors.joining(",", "[", "]")).toString());
    
            System.out.println(Arrays.asList("1", "2", "3", "4", "5").stream().reduce((a, b) -> a.concat(",").concat(b)));
        }
    

  1. JDK1.8-Stream()使用详解 ↩︎

  2. Java 8系列之Stream的基本语法详解 ↩︎

  3. Java 8系列之Stream的强大工具Collector ↩︎

  4. Java 8系列之重构和定制收集器 ↩︎

  5. Java 8系列之Stream中万能的reduce ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值