java stream

Why do you need Stream

As a highlight of Java 8, Stream focuses on various very convenient and efficient aggregation operations (aggregate operations) or bulk data operations (bulk data operations) on collection objects.

  1. A new member introduced by JDK1.8 to process collection data in a declarative manner
  2. Connect basic operations to complete complex data processing pipelines
  3. Provides transparent parallel processing

The difference between streams and collections

  1. time and space
  2. can only be traversed once
  3. External Iteration vs. Internal Iteration

Contrast: Primitive collection operations and Stream collection operations (filtering/mapping/flattening/traversal/sorting/deduplication/skip/truncation application)

composition of flow

Classification of stream operations

stream usage

Raw collection operations and Stream collection operations (application of filtering/mapping/flattening/traversal/sorting/deduplication/skip/truncation)

    public static void main(String[] args) {
        List<StreetAlarmReportVo> voList = new ArrayList<>();
        StreetAlarmReportVo vo = null;
        for (int i = 1; i <= 3; i++) {
            vo = new StreetAlarmReportVo();
            vo.setPlaceName("地点" + i);
            vo.setStreetName("南京街");
            vo.setPlaceTypeName("人流量较大的街");
            vo.setFlowNum(i); // 人流量
            vo.setScanNum(i); //扫码人数
            voList.add(vo);
        }
        /**
         * forEach使用:
         * 循环
         */
        voList.stream().forEach(v ->{
            v.setFlowNum(v.getFlowNum() + 1000);
        });
        /**
         *  map使用:
         *  将一个元素转换成另一个元素,创建一个新的集合
         */
        List<String> streetNameList = voList.stream().map(v -> v.getStreetName()).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(streetNameList));

        /**
         * 不用stream流的处理
         */
        List<String> streetStrList = new ArrayList<>();
        for (String streetName : streetNameList){
            streetStrList.add(streetName);
        }
        System.out.println(JSON.toJSONString(streetStrList));

        /**
         * filter使用:
         * 过滤出集合中符合条件的对象
         */
        voList.stream().filter(v -> v.getStreetName().equals("街道1")).forEach(v -> {
            System.out.println(JSON.toJSONString(v));
        });
        List<String> streetList = voList
                .stream().filter(v -> v.getStreetName().equals("街道1"))
                .map(v -> v.getStreetName()).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(streetList));
        /**
         * sorted使用:
         * 顺序排列,加上reversed()方法为倒叙
         */
        voList.stream().sorted(Comparator.comparing(StreetAlarmReportVo::getFlowNum).reversed()).forEach(v -> {
            System.out.println(v.getFlowNum());
        });
        System.out.println(JSON.toJSONString(voList.get(0)));
        /**
         * list排序
         * 顺序排列,加上reversed()方法为倒叙
         * 使用 Comparator.nullsFirst进行排序,当集合中存在null元素时,可以使用针对null友好的比较器,null元素排在集合的最前面
         * 使用 Comparator.thenComparing 排序,首先使用 flowNum 排序,紧接着在使用scanNum 排序
         */
        voList.sort(Comparator.comparing(StreetAlarmReportVo::getFlowNum).reversed());
        System.out.println("顺序排列,加上reversed()方法为倒叙:" + JSON.toJSONString(voList));
        voList.sort(Comparator.nullsFirst(Comparator.comparing(StreetAlarmReportVo::getFlowNum)).reversed());
        System.out.println("使用 Comparator.nullsFirst进行排序:" + JSON.toJSONString(voList));
        voList.sort(Comparator.comparing(StreetAlarmReportVo::getFlowNum).reversed().thenComparing(StreetAlarmReportVo::getScanNum));
        System.out.println("使用 Comparator.thenComparing 排序:" + JSON.toJSONString(voList));
        /**
         * distinct使用:
         * 对流元素进行去重。有状态操作
         */
        List<String> streets = voList.stream().map(v -> v.getStreetName()).distinct().collect(Collectors.toList());
        System.out.println("去重后的元素:" + JSON.toJSONString(streets));
        /**
         * skip使用:
         * 跳过前N条记录,有状态操作
         */
        List<StreetAlarmReportVo> voList2 = voList.stream().skip(2).collect(Collectors.toList());
        System.out.println("使用skip跳过前两条记录:" + JSON.toJSONString(voList2));
        /**
         * limit使用:
         * 截断前N条记录。有状态操作
         */
        List<StreetAlarmReportVo> voList3 = voList.stream().limit(2).collect(Collectors.toList());
        System.out.println("limit截断前2条记录:" + JSON.toJSONString(voList3));
        /**
         * allMatch使用:
         * 终端操作,短路操作。所有元素匹配,返回true
         * anyMatch使用:
         * 任何元素匹配,返回true
         */
        boolean flag = voList.stream().allMatch(v -> v.getStreetName().equals("南京街"));
        boolean flag2 = voList.stream().anyMatch(v -> v.getStreetName().equals("南京街"));
        System.out.println("集合内的街道名称是否都是南京街:" + flag);
        System.out.println("集合内的街道名称是否有一个是南京街:" + flag);
    }

noneMatch use: no element matches, return true

@Test
    public void noneMatchTest() {
        boolean match = list.stream()

                .peek(sku -> System.out.println(sku.getSkuName()))

                // noneMatch
                .noneMatch(sku -> sku.getTotalPrice() > 10_000);

        System.out.println(match);
    }

findFirst use: find the first

@Test
    public void findFirstTest() {
        Optional<Sku> optional = list.stream()

                .peek(sku -> System.out.println(sku.getSkuName()))

                // findFirst
                .findFirst();

        System.out.println(
                JSON.toJSONString(optional.get(), true));
    }

findAny use: find any one

/**
     * 找任意一个
     */
    @Test
    public void findAnyTest() {
        Optional<Sku> optional = list.stream()

                .peek(sku -> System.out.println(sku.getSkuName()))

                // findAny
                .findAny();

        System.out.println(
                JSON.toJSONString(optional.get(), true));
    }

max use: find the largest

@Test
    public void maxTest() {
        OptionalDouble optionalDouble = list.stream()
                // 获取总价
                .mapToDouble(Sku::getTotalPrice)

                .max();

        System.out.println(optionalDouble.getAsDouble());
    }

min use: find the smallest

@Test
    public void minTest() {
        OptionalDouble optionalDouble = list.stream()
                // 获取总价
                .mapToDouble(Sku::getTotalPrice)

                .min();

        System.out.println(optionalDouble.getAsDouble());
    }

count use: count

@Test
    public void countTest() {
        long count = list.stream()
                .count();

        System.out.println(count);
    }
}

Four Construction Forms of Streams

Build streams directly from values

@Test
    public void streamFromValue() {
        Stream stream = Stream.of(1, 2, 3, 4, 5);

        stream.forEach(System.out::println);
    }

Build streams from arrays

@Test
    public void streamFromArray() {
        int[] numbers = {1, 2, 3, 4, 5};

        IntStream stream = Arrays.stream(numbers);
        stream.forEach(System.out::println);
    }

Generate a stream from a file

@Test
    public void streamFromFile() throws IOException {
        // TODO 此处替换为本地文件的地址全路径
        String filePath = "";

        Stream<String> stream = Files.lines(
                Paths.get(filePath));

        stream.forEach(System.out::println);
    }

Generating streams through functions (infinite streams)

@Test
    public void streamFromFunction() {
//        2,4,6,8...一直无限下去
//        Stream stream = Stream.iterate(0, n -> n + 2);

        Stream stream = Stream.generate(Math::random);
        stream.limit(100)
                .forEach(System.out::println);

    }

Predefined collectors for streams

collection collector

/**
     * 集合收集器
     */
    @Test
    public void toList() {

        List<Sku> list = CartService.getCartSkuList();

        List<Sku> result = list.stream()
                .filter(sku -> sku.getTotalPrice() > 100)

                .collect(Collectors.toList());

        System.out.println(
                JSON.toJSONString(result, true));

    }

group

@Test
    public void group() {
        List<Sku> list = CartService.getCartSkuList();

        // Map<分组条件,结果集合>
        Map<Object, List<Sku>> group = list.stream()
                .collect(
                        Collectors.groupingBy(
                                sku -> sku.getSkuCategory()));

        System.out.println(
                JSON.toJSONString(group, true));
    }

Partition

@Test
    public void partition() {
        List<Sku> list = CartService.getCartSkuList();

        Map<Boolean, List<Sku>> partition = list.stream()
                .collect(Collectors.partitioningBy(
                        sku -> sku.getTotalPrice() > 100));

        System.out.println(
                JSON.toJSONString(partition, true));
    }

The difference between grouping and partitioning

Reduction and aggregation operations (involving parallel execution)

reduction

@Test
    public void reduceTest() {

        /**
         * 订单对象
         */
        @Data
        @AllArgsConstructor
        class Order {
            /**
             * 订单编号
             */
            private Integer id;
            /**
             * 商品数量
             */
            private Integer productCount;
            /**
             * 消费总金额
             */
            private Double totalAmount;
        }

        /*
            准备数据
         */
        ArrayList<Order> list = Lists.newArrayList();
        list.add(new Order(1, 2, 25.12));
        list.add(new Order(2, 5, 257.23));
        list.add(new Order(3, 3, 23332.12));

        /*
            以前的方式:
            1. 计算商品数量
            2. 计算消费总金额
         */

        /*
            汇总商品数量和总金额
         */
        Order order = list.stream()
                .parallel()
                .reduce(
                        // 初始化值
                        new Order(0, 0, 0.0),

                        // Stream中两个元素的计算逻辑
                        (Order order1, Order order2) -> {
                            System.out.println("执行 计算逻辑 方法!!!");

                            int productCount =
                                    order1.getProductCount()
                                            + order2.getProductCount();

                            double totalAmount =
                                    order1.getTotalAmount()
                                            + order2.getTotalAmount();

                            return new Order(0, productCount, totalAmount);
                        },

                        // 并行情况下,多个并行结果如何合并
                        (Order order1, Order order2) -> {
                            System.out.println("执行 合并 方法!!!");

                            int productCount =
                                    order1.getProductCount()
                                            + order2.getProductCount();

                            double totalAmount =
                                    order1.getTotalAmount()
                                            + order2.getTotalAmount();

                            return new Order(0, productCount, totalAmount);
                        });

        System.out.println(JSON.toJSONString(order, true));
    }

operation result

执行 计算逻辑 方法!!!
执行 计算逻辑 方法!!!
执行 计算逻辑 方法!!!
执行 合并 方法!!!
执行 合并 方法!!!
{
    "id":0,
    "productCount":10,
    "totalAmount":23614.469999999998
}

Summarize collect

@Test
    public void collectTest() {
        /**
         * 订单对象
         */
        @Data
        @AllArgsConstructor
        class Order {
            /**
             * 订单编号
             */
            private Integer id;
            /**
             * 用户账号
             */
            private String account;
            /**
             * 商品数量
             */
            private Integer productCount;
            /**
             * 消费总金额
             */
            private Double totalAmount;
        }

        /*
            准备数据
         */
        ArrayList<Order> list = Lists.newArrayList();
        list.add(new Order(1, "zhangxiaoxi", 2, 25.12));
        list.add(new Order(2, "zhangxiaoxi",5, 257.23));
        list.add(new Order(3, "lisi",3, 23332.12));

        /*
            Map<用户账号, 订单(数量和金额)>
         */

        Map<String, Order> collect = list.stream()
                .parallel()
                .collect(
                        () -> {
                            System.out.println("执行 初始化容器 操作!!!");

                            return new HashMap<String, Order>();
                        },
                        (HashMap<String, Order> map, Order newOrder) -> {
                            System.out.println("执行 新元素添加到容器 操作!!!");

                            /*
                                新元素的account已经在map中存在了
                                不存在
                             */
                            String account = newOrder.getAccount();

                            // 如果此账号已存在,将新订单数据累加上
                            if (map.containsKey(account)) {
                                Order order = map.get(account);
                                order.setProductCount(
                                        newOrder.getProductCount()
                                                + order.getProductCount());
                                order.setTotalAmount(
                                        newOrder.getTotalAmount()
                                                + order.getTotalAmount());
                            } else {
                                // 如果不存在,直接将新订单存入map
                                map.put(account, newOrder);
                            }

                        }, (HashMap<String, Order> map1, HashMap<String, Order> map2) -> {
                            System.out.println("执行 并行结果合并 操作!!!");

                            map2.forEach((key, value) -> {
                                map1.merge(key, value, (order1, order2) -> {

                                    // TODO 注意:一定要用map1做合并,因为最后collect返回的是map1
                                    return new Order(0, key,
                                            order1.getProductCount()
                                                    + order2.getProductCount(),
                                            order1.getTotalAmount()
                                                    + order2.getTotalAmount());
                                });
                            });
                        });

        System.out.println(JSON.toJSONString(collect, true));
    }

operation result

执行 初始化容器 操作!!!
执行 初始化容器 操作!!!
执行 初始化容器 操作!!!
执行 新元素添加到容器 操作!!!
执行 新元素添加到容器 操作!!!
执行 新元素添加到容器 操作!!!
执行 并行结果合并 操作!!!
执行 并行结果合并 操作!!!
{
    "lisi":{
        "account":"lisi",
        "id":3,
        "productCount":3,
        "totalAmount":23332.12
    },
    "zhangxiaoxi":{
        "account":"zhangxiaoxi",
        "id":0,
        "productCount":7,
        "totalAmount":282.35
    }
}

Guess you like

Origin blog.csdn.net/qq_32526375/article/details/125371949
Recommended