• java流stream的一些简单用法


    @Data
    @AllArgsConstructor
    public class Student {
        private String name;
        private Integer score;
        private Integer age;
    }
    
    public class StreamTest {
    
        
        /**
         * flatMap 接收一个流的来源(比如list), 返回一个流
         * 将多个流,打平, 使其成为一个流
         */
        @Test
        public void Test3() {
            Stream<List<Integer>> stream = Stream.of(Arrays.asList(1), Arrays.asList(2,3), Arrays.asList(4,5,6));
            stream.flatMap(list -> list.stream()).map(x->x*x).forEach(System.out::println);
    
            List<String> list2 = Arrays.asList("hello world", "world hello", "hello world hello", "hello welcome");
            list2.stream().map(item -> item.split(" ")) // 拆成单词
                    .flatMap(Arrays::stream) // 打平, 将每个数组处理成流
                    .distinct() // 去重, 根据equals方法
                    .forEach(System.out::println);
        }
    
        /**
         * flatMap的更深入使用, 核心就在于将多个stream打平成一个stream, 其入参就是stream类型的
         * 利用两个list交叉打招呼, 相当于两个list的求笛卡尔积
         */
        @Test
        public void Test31() {
            List<String> list1 = Arrays.asList("Hi", "Hello", "你好");
            List<String> list2 = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
    
            List<String> result = list1.stream()
                    .flatMap(item -> list2.stream().map(item2 -> item + " " + item2))
                    .collect(Collectors.toList());
            result.forEach(System.out::println);
        }
    
        @Test
        public void Test4() {
            // generate方法, 传入一个生产者
            Stream<String> stream = Stream.generate(UUID.randomUUID()::toString);
            // findFirst 返回一个 optional
            stream.findFirst().ifPresent(System.out::println);
        }
    
        /**
         * Stream.iterate()
         * 接收一个种子, 和一个行为
         * 这个行为会以种子为初始值, 不断的累加执行,返回一个无限的串行流
         * 所以在使用这个方法时, 一般会加一个limit()方法, 来限制长度
         */
        @Test
        public void Test5() {
            Stream.iterate(1, item -> item + 2)
                    .limit(6)
                    .forEach(System.out::println);
            System.out.println("-------------------------");
            IntSummaryStatistics collect = Stream.iterate(1, item -> item + 2)
                    .limit(6)
                    .filter(x -> x > 2) // 过滤
                    .map(x -> x * 2) // 转换
                    .skip(2)  // 忽略前两个元素
                    .limit(2) // 只取前两个元素
                    .collect(Collectors.summarizingInt(x -> x));// 求出结果集,集中包含很多操作
            System.out.println(collect.getSum());
        }
    
        /**
         * 串行流与并行流的排序时间对比
         * 串行流 : 9619
         */
        @Test
        public void Test6() {
            List<String> list = new ArrayList<>(5000000);
            for (int i = 0; i < 5000000; ++i) {
                list.add(UUID.randomUUID().toString());
            }
            System.out.println("开始排序");
            long startTime = System.nanoTime();
            list.stream().sorted().findFirst();
            long endTime = System.nanoTime();
            long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
            System.out.println("排序耗时: " +millis);
        }
    
        /**
         * 串行流与并行流的排序时间对比
         * 并行流: 2235
         */
        @Test
        public void Test7() {
            List<String> list = new ArrayList<>(5000000);
            for (int i = 0; i < 5000000; ++i) {
                list.add(UUID.randomUUID().toString());
            }
            System.out.println("开始排序");
            long startTime = System.nanoTime();
            list.parallelStream().sorted().findFirst();
            long endTime = System.nanoTime();
            long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
            System.out.println("排序耗时: " +millis);
        }
    
        /**
         * stream还提供了和sql一样的分组功能, 分组结果一般是返回map
         * 根据谁分组, 谁就是key
         */
        @Test
        public void Test8() {
            Student s1 = new Student("zhangsan", 100, 20);
            Student s2 = new Student("lisi", 90, 20);
            Student s3 = new Student("wangwu", 90, 30);
            Student s4 = new Student("zhangsan", 80, 40);
    
            List<Student> students = Arrays.asList(s1, s2, s3, s4);
            // 按名字对学生分组
            /* 传统做法: 
            结果: Map<String, List<Student>>
            * 1. 循环列表
            * 2. 取出学生名字
            * 3. 检查map中是否存在该名字, 不存在直接添加到该map,
            * 存在则将map中的List对象取出来,然后添加到list中
            * 4. 返回map对象
            * */
            // stream做法:
            Map<String, List<Student>> map = students.stream().collect(Collectors.groupingBy(Student::getName));
            map.forEach((key, value) -> System.out.println("key: " + key + "
    value: " + value));
            System.out.println("-----------------------------------------");
    
            // 根据分数来分组
            Map<Integer, List<Student>> map2 = students.stream().collect(Collectors.groupingBy(Student::getScore));
            map2.forEach((key, value) -> System.out.println("key: " + key + "
    value: " + value));
            System.out.println("-----------------------------------------");
    
            // 分组后,返回数量
            Map<String, Long> m3 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting()));
            m3.forEach((key, value) -> System.out.println("key: " + key + "
    value: " + value));
            System.out.println("-----------------------------------------");
    
            // 分组后,返回分数平均值
            Map<String, Double> m4 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore)));
            m4.forEach((key, value) -> System.out.println("key: " + key + "
    value: " + value));
    
        }
    
        /**
         * stream分区, 分区是分组的一种特例, 只把数据分为两组
         * 返回一个map, key是bool类型, 表明是否符合分区条件
         */
        @Test
        public void Test9() {
            Student s1 = new Student("zhangsan", 100, 20);
            Student s2 = new Student("lisi", 90, 20);
            Student s3 = new Student("wangwu", 90, 30);
            Student s4 = new Student("zhangsan", 80, 40);
    
            List<Student> students = Arrays.asList(s1, s2, s3, s4);
            Map<Boolean, List<Student>> map = students.stream()
                    .collect(Collectors.partitioningBy(student -> student.getScore() >= 90));
            map.forEach((key, value) -> System.out.println("key: " + key + "
    value: " + value));
    
        }
    
        @Test
        public void Test() {
            Student s1 = new Student("zhangsan", 80);
            Student s2 = new Student("lisi", 90);
            Student s3 = new Student("wangwu", 100);
            Student s4 = new Student("zhaoliu", 90);
            Student s5 = new Student("zhangsan", 70);
            Student s6 = new Student("wangwu", 50);
            List<Student> students = Arrays.asList(s1, s2, s3, s4, s5, s6);
    
            // 在分组的基础上,再次分组, 先根据分数分组, 再根据名字分组
            Map<Integer, Map<String, List<Student>>> map = students.stream().collect(Collectors.groupingBy(Student::getScore, Collectors.groupingBy(Student::getName)));
            System.out.println(map);
            System.out.println("-------------------------");
            // 两次分区
            Map<Boolean, Map<Boolean, List<Student>>> map2 = students.stream().collect(Collectors.partitioningBy(s -> s.getScore() > 80, Collectors.partitioningBy(s -> s.getScore() > 90)));
            System.out.println(map2);
            System.out.println("-------------------------");
            // 先分区, 再求出分区中学生数量
            Map<Boolean, Long> map3 = students.stream().collect(Collectors.partitioningBy(s -> s.getScore() > 80, Collectors.counting()));
            System.out.println(map3);
            System.out.println("-----------------------------");
            // 先根据名字进行分组, 再收集组中分数最小的学生
            Map<String, Optional<Student>> map4 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.minBy(Comparator.comparingInt(Student::getScore))));
            System.out.println(map4);
            System.out.println("---------------------------------");
            // 对map4 的优化,先根据名字进行分组, 再收集组中分数最小的学生, 由于先分组了,
            // 所以后面比较的时候一定有元素,可以直接get到值,少一次Optional操作
            Map<String, Student> map5 = students.stream()
                    .collect(Collectors.groupingBy(Student::getName,
                            Collectors.collectingAndThen(
                                    Collectors.minBy(Comparator.comparingInt(Student::getScore)),
                                    Optional::get)
                            )
                    );
            System.out.println(map5);
            System.out.println("---------------------------------");
        } 
    }
    
  • 相关阅读:
    selenium+allure测试报告添加测试截图
    selenium pytest_html测试报告添加测试步骤截图
    pytest单元测试框架fixture应用
    unittest单元测试框架教程7-unittest.TestSuite类详解
    unittest单元测试框架教程6-unittest.TestCase类详解
    unittest单元测试框架教程5-使用subTest进行循环测试
    unittest单元测试框架教程3-利用unittest测试原理组织测试套件和用例
    unittest单元测试框架教程2-通过TestLoader运行用例
    Python学习相关链接
    GO语言相关的链接整理
  • 原文地址:https://www.cnblogs.com/Lothlorien/p/12142626.html
Copyright © 2020-2023  润新知