zoukankan      html  css  js  c++  java
  • Stream (四)之Collectors集合类常用方法

    Stream (四)之Collectors集合类常用方法

    package com.zy.stream.collect;
    
    import com.zy.stream.model.Apple;
    import com.zy.stream.model.Person;
    import org.junit.Test;
    
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    /**
     * Stream流中关于Collectors集合类中的相关方法,详解
     **/
    
    public class StreamCollectTest {
    
     //实体类 
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
         class Apple {
    
            private String color;
            private Integer weight;
    
    
        }
      
        @Data
        @Builder(toBuilder = true)
        @AllArgsConstructor
        @NoArgsConstructor
         class Person {
    
            private String firstName, lastName, job, gender;
            private int salary,age;
    
        }
    
    
        List<Person> listPerson1= new ArrayList<Person>() {
            {
                add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 2000, 18));
                add(new Person("Tamsen", "Brittany", "Java programmer", "female", 2371, 55));
                add(new Person("Floyd", "Donny", "Java programmer", "male", 3322, 25));
                add(new Person("Sindy", "Jonie", "Java programmer", "female", 35020, 15));
                add(new Person("Vere", "Hervey", "Java programmer", "male", 2272, 25));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 2057, 870));
                add(new Person("testMaude", null, "Java programmer", "female", 2057, 870));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 2057, 87));
                add(new Person("Shawn", "Randall", "Java programmer", "male", 3120, 99));
                add(new Person("Jayden", "Corrina", "Java programmer", "female", 345, 25));
                add(new Person("Palmer", "Dene", "Java programmer", "male", 3375, 14));
                add(new Person("Addison", "Pam", "Java programmer", "female", 3426, 20));
            }
        };
        List<Person> listPerson2= new ArrayList<Person>() {
            {
                add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 2000, 18));
                add(new Person("Tamsen", "Brittany", "Java programmer", "female", 2371, 55));
                add(new Person("testFloyd", "Donny", "Java programmer", "male", 3322, 25));
                add(new Person("Sindy", "Jonie", "Java programmer", "female", 35020, 15));
                add(new Person("testVere", "Hervey", "Java programmer", "male", 2272, 25));
                add(new Person("Maude", "Jaimie", "Java programmer", "female", 2057, 87));
                add(new Person("testShawn", "Randall", "Java programmer", "male", 3120, 99));
                add(new Person("Jayden", "Corrina", "Java programmer", "female", 345, 25));
                add(new Person("testPalmer", "Dene", "Java programmer", "male", 3375, 14));
                add(new Person("Addison", "Pam", "Java programmer", "female", 3426, 20));
            }
        };
    
    
        @Test
        public void testAll(){
    
            List<Integer> collect = listPerson1.stream().map(Person::getSalary).collect(Collectors.toList());
    
    
            //交集 (list1 + list2)
            System.out.println("test=======交集[firstName中不含有test] ========>:");
            listPerson1.stream()
                        .filter(listPerson2::contains)
                        .collect(Collectors.toList())
                        .forEach(System.out::println);
    
            //差集 取差集是注意以那个集合为主
            System.out.println("test=======listPerson2差集[firstName中含有test] ========>:");
            listPerson2.stream()
                        .filter(e-> !listPerson1.contains(e))
                        .collect(Collectors.toList())
                        .forEach(System.out::println);
    
            //并集
            System.out.println("test=======并集[两个集合的所有元素] ========>:");
            List<Person> collect1 = listPerson1.parallelStream().collect(Collectors.toList());
            collect1.addAll(listPerson2.parallelStream().collect(Collectors.toList()));
            collect1.stream().forEach(System.out::println);
            System.out.println("test=======并集[两个集合的所有元素] 去重========>:");
            collect1.stream().distinct().forEach(System.out::println);
    
    
            HashMap<String, Integer> map = new HashMap<>();
            map.put("Apple1",30);
            map.put("Apple2",20);
            map.put("Apple3",10);
            map.put("Apple6",51);
            map.put("Apple4",99);
    
            System.out.println("test=======Map集合转 List[注意数据类型]按照key值排序========>:");
            //Map集合转 List
            map.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey()))
                    .map(e -> new Apple(e.getKey(), e.getValue())).collect(Collectors.toList())
                    .forEach(System.out::println);
    
            System.out.println("test=======Map集合转 List[注意数据类型]按照value值排序========>:");
            map.entrySet()
                    .stream()
                    .sorted(Comparator.comparing(Map.Entry::getValue)).map(e -> new Apple(e.getKey(), e.getValue()))
                    .collect(Collectors.toList())
                    .forEach(System.out::println);
    
            System.out.println("test=======Map集合转 List[注意数据类型]按照key值排序Entry.comparingByKey()========>:");
            map.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByKey())
                .map(e -> new Apple(e.getKey(), e.getValue()))
                .collect(Collectors.toList())
                .forEach(System.out::println);
    
    
            //toList()方法
            List<Integer> collectList = Stream.of(1, 2, 3, 4)
                    .collect(Collectors.toList());
            System.out.println("test=======Collectors.toList()========》: " + collectList);
    
    
    
            HashMap<String, Object> objMap = new HashMap<>();
            //List转map集合    Collectors.toMap方法的第三个参数为键值重复处理策略,如果不传入第三个参数,当有相同的键时,会抛出一个IlleageStateException。
            System.out.println("test=======List元素对象转map集合[方式一]========>:");
            /*  toMap()参数一:key值,参数二:value值 参数三:当两个key值相同时,决定保留前一个value值还是后一个value值
                 key为null    可以为null
                字典查询和数据转换 toMap时,如果value为null,会报空指针异常,需要校验
             */
            listPerson1.stream()
                    .collect(Collectors.toMap(p -> p.getFirstName(), p -> Optional.ofNullable(p.getLastName()).orElse("value为null加非空检验"), (k1, k2) -> k1))
                    .forEach(
                            (key, value) -> {
                            //map集合forEach()循环时传两个参数,key,value值,
                            System.out.println("key: " + key + "    value: " + value);
                    }
            );
    
            /*下面这种形式,通过方法的引用也可以去取重复的key,保证不抛出异常,但是只能保证出现的第一个key的数据(Map::putAll)
                key为null    可以为null
                value为null,不会报空指针异常
             */
            System.out.println("test=======List元素对象转map集合[方式二]========>:");
            listPerson1.stream()
                        .collect(HashMap::new,(maps,p)->maps.put(p.getFirstName(),p.getLastName()),Map::putAll)
                        .forEach(
                            (key, value) -> {
                                //map集合forEach()循环时传两个参数,key,value值,
                                //如果value为null 打印:key: testMaude    value: null
                                System.out.println("++key: " + key + "    ++value: " + value);
                        }
            );
            System.out.println("test=======List元素对象转map集合[方式三]========>:");
            Stream<Apple> appleStream = Stream.of(new Apple("白色", 18),
                                                new Apple("红色", 180),
                                                new Apple("绿色", 187),
                                                new Apple("银色", 19));
    
            Map<String , Apple> appleMap = appleStream.collect(Collectors.toMap(Apple::getColor, i -> i));
            appleMap.forEach(
                    (key, value) -> {
                        System.out.println("appleKey: " + key + "    appleValue: " + value);
                    }
            );
    
            System.out.println("test========假设要得到按年龄分组的Map<Integer,List>:=======>:");
            Map<Integer, List<Person>> ageMap = listPerson1.stream().collect(Collectors.toMap(Person::getAge, Collections::singletonList, (a, b) -> {
                List<Person> resultList = new ArrayList<>(a);
                resultList.addAll(b);
                return resultList;
            }));
            ageMap.forEach(
                    (key, value) -> {
                        System.out.println("ageKey: " + key + "   personValue: " + value);
                    }
            );
    
            //List<String> 转String
            System.out.println("test========List<String> 转String使用Collectors.joining():=======>:");
            String str = Arrays.asList("voidcc.com", "voidmvn.com", "voidtool.com").stream().collect(Collectors.joining(","));
            System.out.println(str);
    
            //排序
            System.out.println("test=======排序sorted()========>:");
            //按照自然顺序进行排序 如果要自定义排序sorted 传入自定义的 Comparator
            listPerson1.stream().map(Person::getAge).sorted((x,y)->x.compareTo(y)).forEach(System.out::println);
    
    
            //比较
            System.out.println("test=======比较sorted()========>:");
            Comparator<Person> comparator = (p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName());
    
            Person p1 = new Person("Addison", "Pam", "Java programmer", "female", 3426, 20);
            Person p2 = new Person("Addison", "Pam", "Java programmer", "female", 3426, 20);
    
            comparator.compare(p1, p2);             // > 0
            comparator.reversed().compare(p1, p2);  // < 0
    
    
            //分组
            System.out.println("test=======按照薪资分组Collectors.groupingBy()=====返回map===>:");
            listPerson1.stream().collect(Collectors.groupingBy(Person::getSalary)).forEach(
                    (key, value) -> {System.out.println("key: " + key + "    value: " + value);}
            );
            /*
             * groupingBy 分组后操作
                    //Collectors中还提供了一些对分组后的元素进行downStream处理的方法:
                    //counting方法返回所收集元素的总数;
                    //summing方法会对元素求和;
                    //maxBy和minBy会接受一个比较器,求最大值,最小值;
                    //mapping函数会应用到downstream结果上,并需要和其他函数配合使用;
             */
    
            Map<Integer, Long> count = listPerson1.stream().collect(Collectors.groupingBy(Person::getSalary,Collectors.counting()));
            count.forEach((key, value) -> {System.out.println("counting方法返回所收集元素的总数:--->key: " + key + "    value: " + value);});
    
            Map<Integer, Integer> ageCount = listPerson1.stream().collect(Collectors.groupingBy(Person::getSalary,Collectors.summingInt(Person::getAge)));
            ageCount.forEach((key, value) -> {System.out.println("summing方法会对元素求和:--->key: " + key + "    value: " + value);});
    
            Map<Integer, Optional<Person>> ageMax =  listPerson1.stream().collect(Collectors.groupingBy(Person::getSalary,Collectors.maxBy(Comparator.comparing(Person::getAge))));
            ageMax.forEach((key, value) -> {System.out.println("maxBy和minBy会接受一个比较器,求最大值,最小值:--->key: " + key + "    value: " + value);});
    
            Map<Integer, List<String>> nameMap =  listPerson1.stream().collect(Collectors.groupingBy(Person::getSalary,Collectors.mapping(Person::getFirstName,Collectors.toList())));
            nameMap.forEach((key, value) -> {System.out.println("mapping函数会应用到downstream结果上,并需要和其他函数配合使用: " + key + "    value: " + value);});
    
            /*
             *1.    Collectors partitioningBy
             *      Collectors中还提供了partitioningBy方法,接受一个Predicate函数,该函数返回boolean值,用于将内容分为两组。
             *
             *2.    Collectors joining
             *      Collectors.joining 收集Stream中的值,该方法可以方便地将Stream得到一个字符串。joining函数接受三个参数,分别表示允(用以分隔元素)、前缀和后缀
             *
             *  Collectors分别提供了求平均值averaging、总数couting、最小值minBy、最大值maxBy、求和suming等操作。
             *  但是假如你希望将流中结果聚合为一个总和、平均值、最大值、最小值,
             *  那么Collectors.summarizing(Int/Long/Double)就是为你准备的,
             *  它可以一次行获取前面的所有结果,其返回值为(Int/Long/Double)SummaryStatistics。
             *
             *
             * 使用collect可以将Stream转换成值。maxBy和minBy允许用户按照某个特定的顺序生成一个值。
                    averagingDouble:求平均值,Stream的元素类型为double
                    averagingInt:求平均值,Stream的元素类型为int
                    averagingLong:求平均值,Stream的元素类型为long
                    counting:Stream的元素个数
                    maxBy:在指定条件下的,Stream的最大元素
                    minBy:在指定条件下的,Stream的最小元素
                    reducing: reduce操作
                    summarizingDouble:统计Stream的数据(double)状态,其中包括count,min,max,sum和平均。
                    summarizingInt:统计Stream的数据(int)状态,其中包括count,min,max,sum和平均。
                    summarizingLong:统计Stream的数据(long)状态,其中包括count,min,max,sum和平均。
                    summingDouble:求和,Stream的元素类型为double
                    summingInt:求和,Stream的元素类型为int
                    summingLong:求和,Stream的元素类型为long
             *
             */
    
    
        }
    }
    
  • 相关阅读:
    mysql 下 计算 两点 经纬度 之间的距离
    富爸爸财务自由之路
    Ubuntu16.04忘记MySQL5.7的root用户密码之解决方案
    Windowns下code: command not found
    Linux下CRMEB环境搭建
    PHP无法使用curl_init()函数
    请在mysql配置文件修sql-mode或sql_mode为NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    apache不能解析php之解决办法
    windows上hexo: command not found
    SyntaxError: Non-ASCII character 'æ' in file csdn.py on line 7, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
  • 原文地址:https://www.cnblogs.com/MrYuChen-Blog/p/14074488.html
Copyright © 2011-2022 走看看