精华内容
下载资源
问答
  • 主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下
  • Java Stream API Parallel Collectors - 克服标准并行流的限制 Parallel Collectors 是一个工具包,使用 Stream API 简化 Java 中的并行收集处理......但没有标准并行流强加的限制。 list.stream() .collect...
  • 阿里云MaxCompute数据收集器 ... $ cd aliyun-maxcompute-data-collectors $ mvn clean package -DskipTests=true -Dmaven.javadoc.skip=true 插件包位于每个插件子项目的target 。 用法 请参考的基本用法。
  • 主要介绍了Java8 Stream Collectors收集器使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Collectors 中提供了很多好用的 Collector 实现,大大提高了我们的生产力,比如,将元素放入 Collection,一些聚合、汇总、分组操作。 转集合:toCollection、toList、toSet toCollection() 可以转成任意的 ...

    Collectors 中提供了很多好用的 Collector 实现,大大提高了我们的生产力,比如,将元素放入 Collection,一些聚合、汇总、分组操作。

    转集合:toCollection、toList、toSet

    • toCollection() 可以转成任意的 Collection 实现类
    • toList 转成 ArrayList
    • toSet 转成 HashSet
    public static void main(String[] args) {
        String[] arr = {"a", "b", "c", "d"};
        toCollection(arr);
    }
    
    public static void toCollection(String[] arr) {
        ArrayList<String> list1 = Arrays.stream(arr).collect(Collectors.toCollection(ArrayList::new));
        System.out.println(list1);
    
        List<String> list2 = Arrays.stream(arr).collect(Collectors.toList());
        System.out.println(list2);
    
        Set<String> set = Arrays.stream(arr).collect(Collectors.toSet());
        System.out.println(set);
    }
    
    [a, b, c, d]
    [a, b, c, d]
    [a, b, c, d][a, b, c, d]
    

    转Map:toMap、toConcurrentMap

    toMap

    // 创建 HashMap,有重复 key 时抛异常 java.lang.IllegalStateException: Duplicate key
    public static <T, K, U>
        Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                        Function<? super T, ? extends U> valueMapper);
    
    // 在上面的基础上,当出现 key 重复时,自定义对 value 的处理策略,(阿里手册强制使用)。
    public static <T, K, U>
        Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                        Function<? super T, ? extends U> valueMapper,
                                        BinaryOperator<U> mergeFunction)
    
    // 在上面的基础上,可以自由控制 Map 的类型
    public static <T, K, U, M extends Map<K, U>>
        Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                                 Function<? super T, ? extends U> valueMapper,
                                 BinaryOperator<U> mergeFunction,
                                 Supplier<M> mapSupplier)
    
    @Data
    private static class Person {
        private String name;
    
        private String address;
    
        public Person(String name, String address) {
            this.name = name;
            this.address = address;
        }
    
        public static Person of(String name, String address) {
            return new Person(name, address);
        }
    }
    
    public static void toMap(List<Person> list) {
        Map<String, String> map1 = list.stream().collect(Collectors.toMap(
                Person::getName, Person::getAddress, (v1, v2) -> v1 + " " + v2, TreeMap::new));
    
        Map<String, String> map2 = list.stream().collect(Collectors.toMap(
                Person::getName, Person::getAddress, (v1, v2) -> v1 + " " + v2));
    
        System.out.println(map1.getClass() + " - " + map1);
        System.out.println(map2.getClass() + " - " + map2);
    
        Map<String, String> map3 = list.stream().collect(Collectors.toMap(
                Person::getName, Person::getAddress));
        System.out.println(map3.getClass() + " - " + map3);
    }
    

    没有重复 key

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", "北京"));
        list.add(Person.of("李四", "上海"));
        list.add(Person.of("王五", "深圳"));
        toMap(list);
    }
    
    class java.util.TreeMap - {张三=北京, 李四=上海, 王五=深圳}
    class java.util.HashMap - {李四=上海, 张三=北京, 王五=深圳}
    class java.util.HashMap - {李四=上海, 张三=北京, 王五=深圳}
    

    存在重复 key

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", "北京"));
        list.add(Person.of("李四", "上海"));
        list.add(Person.of("李四", "深圳"));
        toMap(list);
    }
    
    class java.util.TreeMap - {张三=北京, 李四=上海 深圳}
    class java.util.HashMap - {李四=上海 深圳, 张三=北京}
    Exception in thread "main" java.lang.IllegalStateException: Duplicate key 上海
    	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
    	at java.util.HashMap.merge(HashMap.java:1254)
    	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
    	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
    	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
    	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    	at com.example.heima.collectors.ToMap1.toMap(ToMap1.java:39)
    	at com.example.heima.collectors.ToMap1.main(ToMap1.java:26)
    

    toConcurrentMap

    toMap 的几个方法相似,但会创建 ConcurrentMap

    
    public static <T, K, U>
    	Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
                                                        Function<? super T, ? extends U> valueMapper) 
    
    public static <T, K, U>
    	Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
                    									Function<? super T, ? extends U> valueMapper,
                    									BinaryOperator<U> mergeFunction)
    
    public static <T, K, U, M extends ConcurrentMap<K, U>>
    	Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
                                           Function<? super T, ? extends U> valueMapper,
                                           BinaryOperator<U> mergeFunction,
                                           Supplier<M> mapSupplier) 
    

    字符串拼接:joining

    // 直接拼接,没有分隔符
    public static Collector<CharSequence, ?, String> joining()
    
    // 指定分隔符
    public static Collector<CharSequence, ?, String> joining(CharSequence delimiter)
    
    // 指定分隔符、前缀、后缀
    public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
                                                             CharSequence prefix,
                                                             CharSequence suffix)
    
    public static void main(String[] args) {
        String[] arr = {"a", "b", "c", "d"};
        List<String> list = Arrays.asList(arr);
    
        String s1 = list.stream().collect(Collectors.joining());
        String s2 = list.stream().collect(Collectors.joining(","));
        String s3 = list.stream().collect(Collectors.joining(",", "[", "]"));
    
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }
    
    abcd
    a,b,c,d
    [a,b,c,d]
    

    适配器:mapping

    // 先执行一个 mapper,将T 映射成 U,再执行另一个 Collector
    public static <T, U, A, R>
    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
                               Collector<? super U, A, R> downstream)
    
    public static void main(String[] args) {
        String[] arr = {"a", "ab", "abc"};
    
        List<Integer> list = Arrays.stream(arr).collect(
                Collectors.mapping(String::length, Collectors.toList()));
    
        System.out.println(list);
    }
    
    [1, 2, 3]
    

    先归纳再处理:collectingAndThen

    // 先执行 downstream,然后将 downstream 的返回值 R 转为 RR 类型
    public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
                                                                Function<R,RR> finisher)
    
    // 先转 Set,再取 size
    public static void main(String[] args) {
        String[] arr = {"a", "b", "c", "d", "a", "b"};
        
        int size = Arrays.stream(arr).collect(
            	Collectors.collectingAndThen(Collectors.toSet(), Set::size));
    
        System.out.println(size);
    }
    
    4
    

    聚合操作

    计数:counting

    public static void main(String[] args) {
        String[] arr = {"a", "b", "c", "d"};
        Long count = Arrays.stream(arr).collect(Collectors.counting());
        System.out.println(count);
    }
    
    4
    

    最大最小值:maxBy、minBy

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", 18));
        list.add(Person.of("李四", 25));
        list.add(Person.of("王五", 15));
    
        Optional<Person> min = list.stream().collect(
            	Collectors.minBy(Comparator.comparingInt(Person::getAge)));
        Optional<Person> max = list.stream().collect(
            	Collectors.maxBy(Comparator.comparingInt(Person::getAge)));
        
        System.out.println(min);
        System.out.println(max);
    }
    
    @Data
    @AllArgsConstructor
    private static class Person {
        private String name;
    
        private int age;
    
        public static Person of(String name, int age) {
            return new Person(name, age);
        }
    }
    
    Optional[MinMax.Person(name=王五, age=15)]
    Optional[MinMax.Person(name=李四, age=25)]
    

    求和:summingInt、summingLong、summingDouble

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", 18));
        list.add(Person.of("李四", 25));
        list.add(Person.of("王五", 15));
    
        Integer ageSum = list.stream().collect(Collectors.summingInt(Person::getAge));
        Integer lengthSum = list.stream().collect(Collectors.summingInt((p) -> p.getName().length()));
    
        System.out.println(ageSum);
        System.out.println(lengthSum);
    }
    
    
    @Data
    @AllArgsConstructor
    private static class Person {
        private String name;
    
        private int age;
    
        public static Person of(String name, int age) {
            return new Person(name, age);
        }
    }
    
    58
    6
    

    平均数:averagingInt、averagingLong、averagingDouble

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", 18));
        list.add(Person.of("李四", 25));
        list.add(Person.of("王五", 15));
    
        Double ageAvg = list.stream().collect(Collectors.averagingInt(Person::getAge));
        Double lengAvg = list.stream().collect(Collectors.averagingInt((p) -> p.getName().length()));
    
        System.out.println(ageAvg);
        System.out.println(lengAvg);
    }
    
    
    @Data
    @AllArgsConstructor
    private static class Person {
        private String name;
    
        private int age;
    
        public static Person of(String name, int age) {
            return new Person(name, age);
        }
    }
    
    19.333333333333332
    2.0
    

    reducing

    BinaryOperator 是一个二元的函数,BinaryOperator<T> extends BiFunction<T,T,T>,输入两个参数,返回一个结果,且参数和返回值都是相同类型的 。

    reducing()返回的 Collector 会利用 BinaryOperator 进行元素的 reduce 操作,即 (T, T) -> T

    // 利用 op 对元素执行 reduce 操作,返回值为 Optional<T>
    public static <T> Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op)
    
    // 在上面的基础上添加了初始值 identity,
    public static <T> Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op)
    
    // 在上面的基础上添加了 mapper 函数,可将输入的元素从类型 T 转换成 U,再进行 reduce 操作
    public static <T, U> Collector<T, ?, U> reducing(U identity,
                                    				 Function<? super T, ? extends U> mapper,
                                    				 BinaryOperator<U> op)
    

    实现 minBy、maxBy 功能

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", 18));
        list.add(Person.of("李四", 25));
        list.add(Person.of("王五", 15));
    
        Optional<Person> min = list.stream().collect(
            	Collectors.reducing(BinaryOperator.minBy(Comparator.comparingInt(Person::getAge))));
        Optional<Person> max = list.stream().collect(
            	Collectors.reducing(BinaryOperator.maxBy(Comparator.comparingInt(Person::getAge))));
    
        System.out.println(min);
        System.out.println(max);
    }
    
    
    @Data
    @AllArgsConstructor
    private static class Person {
        private String name;
    
        private int age;
    
        public static Person of(String name, int age) {
            return new Person(name, age);
        }
    }
    
    Optional[Reducing1.Person(name=王五, age=15)]
    Optional[Reducing1.Person(name=李四, age=25)]
    

    实现 counting 功能

    public static void main(String[] args) {
        String[] arr = {"a", "b", "c", "d"};
        Long count = Arrays.stream(arr).collect(Collectors.reducing(0L, e -> 1L, Long::sum));
        System.out.println(count);
    }
    
    4
    

    按 city 分组,每个城市的最高身高

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("北京", 160));
        list.add(Person.of("北京", 181));
        list.add(Person.of("上海", 179));
        list.add(Person.of("上海", 171));
        list.add(Person.of("深圳", 190));
        list.add(Person.of("深圳", 166));
    
        Map<String, Integer> map = list.stream().collect(Collectors.groupingBy(Person::getCity, 
                Collectors.reducing(0, Person::getHeight,
                    BinaryOperator.maxBy(Comparator.comparing(Function.identity())))));
    
        System.out.println(map);
    }
    
    @Data
    @AllArgsConstructor
    private static class Person {
    
        private String city;
    
        private int height;
    
        public static Person of(String city, int height) {
            return new Person(city, height);
        }
    }
    
    {上海=179, 深圳=190, 北京=181}
    

    分组:groupingBy、groupingByConcurrent

    groupingBy

    // 按照 classifier 的返回值进行分组,默认创建 HashMap,key 为 classifier 的返回值,value 为输入元素的 List
    public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(
        										Function<? super T, ? extends K> classifier)
    
    // 上面的基础上,Map 的 value 类型由 downstream 指定,比如 Collectors.toSet()
    public static <T, K, A, D>
    	Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                          	  Collector<? super T, A, D> downstream) 
    
    // 在上面的基础上,有 mapFactory 创建 Map,比如 TreeMap::new
    public static <T, K, D, A, M extends Map<K, D>>
    	Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
                                  	  Supplier<M> mapFactory,
                                  	  Collector<? super T, A, D> downstream)
    
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("北京", "张三"));
        list.add(Person.of("上海", "李四"));
        list.add(Person.of("深圳", "王五"));
        list.add(Person.of("北京", "小明"));
        list.add(Person.of("深圳", "小红"));
    
        groupingBy(list);
    }
    
    public static void groupingBy(List<Person> list) {
        Map<String, List<Person>> map1 = list.stream().collect(
            	Collectors.groupingBy(Person::getCity));
    
        Map<String, Set<Person>> map2 = list.stream().collect(
            	Collectors.groupingBy(Person::getCity, Collectors.toSet()));
    
        TreeMap<String, Set<Person>> map3 = list.stream().collect(
            	Collectors.groupingBy(Person::getCity, TreeMap::new, Collectors.toSet()));
    
        TreeMap<String, Set<String>> map4 = list.stream().collect(
            	Collectors.groupingBy(Person::getCity, TreeMap::new, 
                                      Collectors.mapping(Person::getName, Collectors.toSet())));
    
        System.out.println(map1.getClass() + " - " + map1);
        System.out.println(map2.getClass() + " - " + map2);
        System.out.println(map3.getClass() + " - " + map3);
        System.out.println(map4.getClass() + " - " + map4);
    }
    
    
    @Data
    @AllArgsConstructor
    private static class Person {
        private String city;
    
        private String name;
    
        public static Person of(String city, String name) {
            return new Person(city, name);
        }
        
        @Override
        public String toString() {
            return city + "<=" + name;
        }
    }
    
    class java.util.HashMap - {上海=[上海<=李四], 深圳=[深圳<=王五, 深圳<=小红], 北京=[北京<=张三, 北京<=小明]}
    class java.util.HashMap - {上海=[上海<=李四], 深圳=[深圳<=小红, 深圳<=王五], 北京=[北京<=小明, 北京<=张三]}
    class java.util.TreeMap - {上海=[上海<=李四], 北京=[北京<=小明, 北京<=张三], 深圳=[深圳<=小红, 深圳<=王五]}
    class java.util.TreeMap - {上海=[李四], 北京=[张三, 小明], 深圳=[王五, 小红]}
    

    groupingByConcurrent

    groupingBy 功能类似,但返回 ConcurrentMap

    public static <T, K> Collector<T, ?, ConcurrentMap<K, List<T>>>
        groupingByConcurrent(Function<? super T, ? extends K> classifier) 
        
    public static <T, K, A, D>
        Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(
        										Function<? super T, ? extends K> classifier,
                                                Collector<? super T, A, D> downstream)
                                                                  
    public static <T, K, A, D, M extends ConcurrentMap<K, D>>
        Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
                                                Supplier<M> mapFactory,
                                                Collector<? super T, A, D> downstream)
    

    分区:partitioningBy

    只会分成 TRUE、FALSE 两个区

    // 根据 predicate 进行分区,返回值为 Map<Boolean, List<T>>
    public static <T>
        Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate)
    
    // 根据 predicate 进行分区,返回值为 Map<Boolean, D>,D 是 downstream 的返回值
    public static <T, D, A>
        Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
                                                        Collector<? super T, A, D> downstream)
    
    public static void main(String[] args) {
        String[] arr = {"a", "bb", "ccc", "dddd", "eeeee"};
        Map<Boolean, List<String>> map1 = Arrays.stream(arr).collect(
            	Collectors.partitioningBy(e -> e.length() > 2));
    
        Map<Boolean, Set<String>> map2 = Arrays.stream(arr).collect(
            	Collectors.partitioningBy(e -> e.length() > 2, Collectors.toSet()));
    
        System.out.println(map1);
        System.out.println(map2);
    }
    
    {false=[a, bb], true=[ccc, dddd, eeeee]}
    {false=[bb, a], true=[ccc, eeeee, dddd]}
    

    统计信息:summarizingInt、summarizingLong、summarizingDouble

    返回的统计信息包括:sum、count、average、min、max

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(Person.of("张三", 18));
        list.add(Person.of("李四", 25));
        list.add(Person.of("王五", 15));
    
        IntSummaryStatistics statistics = list.stream().collect(Collectors.summarizingInt(Person::getAge));
    
        System.out.println(statistics);
    }
    
    
    @Data
    @AllArgsConstructor
    private static class Person {
        private String name;
    
        private int age;
    
        public static Person of(String name, int age) {
            return new Person(name, age);
        }
    }
    
    IntSummaryStatistics{count=3, sum=58, min=15, average=19.333333, max=25}
    

    参考

    展开全文
  • Collectors

    2017-12-04 11:04:15
    Class Collectors java.lang.Object java.util.stream.Collectors public final class Collectors extends Object Implementations of Collector that implement various useful ...

    Class Collectors



    • public final class Collectors
      extends Object
      Implementations of  Collector that implement various useful reduction operations, such as accumulating elements into collections, summarizing elements according to various criteria, etc.

      The following are examples of using the predefined collectors to perform common mutable reduction tasks:

      
           // Accumulate names into a List
           List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
      
           // Accumulate names into a TreeSet
           Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
      
           // Convert elements to strings and concatenate them, separated by commas
           String joined = things.stream()
                                 .map(Object::toString)
                                 .collect(Collectors.joining(", "));
      
           // Compute sum of salaries of employee
           int total = employees.stream()
                                .collect(Collectors.summingInt(Employee::getSalary)));
      
           // Group employees by department
           Map<Department, List<Employee>> byDept
               = employees.stream()
                          .collect(Collectors.groupingBy(Employee::getDepartment));
      
           //* Compute sum of salaries by department
           Map<Department, Integer> totalByDept
               = employees.stream()
                          .collect(Collectors.groupingBy(Employee::getDepartment,
                                                         Collectors.summingInt(Employee::getSalary)));
      
           // Partition students into passing and failing
           Map<Boolean, List<Student>> passingFailing =
               students.stream()
                       .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
    展开全文
  • Java8 Stream之Collectors

    千次阅读 2021-06-09 09:39:59
    Collectors 是 Java 8 加入的操作类,位于 java.util.stream 包下。它会根据不同的策略将元素收集归纳起来,比如最简单常用的是将元素装入Map、Set、List等可变容器中


    Collectors 是 Java 8 加入的操作类,位于 java.util.stream 包下。它会根据不同的策略将元素收集归纳起来,比如最简单常用的是将元素装入 Map、Set、List等可变容器中

    toList、toSet

    Collector<T, ?, List<T>> toList() 
    返回一个将输入元素累积到新List中的Collector
    
    Collector<T, ?, Set<T>> toSet() 
    返回一个将输入元素累积到新Set中的Collector
    
    Stream<String> language = Stream.of("java", "php","java");
    List<String> list = language.collect(Collectors.toList());
    System.out.println(list);//[java, php, java]
    
    Stream<String> language1 = Stream.of("java", "php","java");
    Set<String> set = language1.collect(Collectors.toSet());
    System.out.println(set);//[java, php]
    

    toMap

    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)
    返回一个将输入元素累积到新map中的Collector,keyMapper生成key的函数,valueMapper生成value的函数,当可以相同时报错java.lang.IllegalStateException: Duplicate key
    
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction)
    返回一个将输入元素累积到新map中的Collector,keyMapper生成key的函数,valueMapper生成value的函数,mergeFunction处理相同key的元素
    
    Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
    返回一个将输入元素累积到新map中的Collector,keyMapper生成key的函数,valueMapper生成value的函数,mergeFunction处理相同key的元素,mapSupplier一个函数,它返回一个新的指定实现类的空Map ,结果将插入其中
    
    Stream<String> language2 = Stream.of("java", "php");
    Map<String, Integer> map = language2.collect(Collectors.toMap(o -> o, o -> o.length()));
    System.out.println(map);//{java=4, php=3}
    
    Stream<String> language21 = Stream.of("java", "php","java");
    Map<String, Integer> map21 = language21.collect(Collectors.toMap(o -> o, o -> o.length(), (o1, o2) ->  o1));
    System.out.println(map21);//{java=4, php=3}
    
    Stream<String> language22 = Stream.of("java", "php","java");
    LinkedHashMap<String, Integer> map22 = language22.collect(Collectors.toMap(o -> o, o -> o.length(), (o1, o2) ->  o1, LinkedHashMap::new));
    System.out.println(map22);//{java=4, php=3}
    

    toConcurrentMap

    和toMap相似,但是使用并发ConcurrentMap承装

    Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)
    返回一个将输入元素累积到新并发map中的Collector,keyMapper生成key的函数,valueMapper生成value的函数,当可以相同时报错java.lang.IllegalStateException: Duplicate key
    
    Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction)
    返回一个将输入元素累积到新map中的Collector,keyMapper生成key的函数,valueMapper生成value的函数,mergeFunction处理相同key的元素
    
    Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
    返回一个将输入元素累积到新map中的Collector,keyMapper生成key的函数,valueMapper生成value的函数,mergeFunction处理相同key的元素,mapSupplier一个函数,它返回一个新的指定实现类的空Map ,结果将插入其中
    
    Stream<String> language4 = Stream.of("java", "php");
    ConcurrentMap<String, Integer> concurrentMap = language4.collect(Collectors.toConcurrentMap(o -> o, o -> o.length()));
    System.out.println(concurrentMap);//{java=4, php=3}
    
    Stream<String> language41 = Stream.of("java", "php","java");
    ConcurrentMap<String, Integer> concurrentMap1 = language41.collect(Collectors.toConcurrentMap(o -> o, o -> o.length(), (o1, o2) ->  o1));
    System.out.println(concurrentMap1);//{java=4, php=3}
    
    Stream<String> language42 = Stream.of("java", "php","java");
    ConcurrentMap<String, Integer> concurrentMap2 = language42.collect(Collectors.toConcurrentMap(o -> o, o -> o.length(), (o1, o2) ->  o1, ConcurrentHashMap::new));
    System.out.println(concurrentMap2);//{java=4, php=3}
    

    toCollection

    指定承装集合类型

    Collector<T, ?, C> toCollection(Supplier<C> collectionFactory)
    返回一个将输入元素累积到一个新的指定实现类的Collection
    Stream<String> language3 = Stream.of("java", "php","java");
    ArrayList<String> arrayList = language3.collect(Collectors.toCollection(ArrayList::new));
    System.out.println(arrayList);//[java, php, java]
    

    joining

    拼接元素

    Collector<CharSequence, ?, String> joining() 
    返回一个Collector ,它按照遇到的顺序将输入元素连接成一个String
    
    Collector<CharSequence, ?, String> joining(CharSequence delimiter) 
    返回一个以遇到顺序连接输入元素的Collector ,由指定的分隔符分隔
    
    Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
     返回一个Collector ,它按遇到顺序连接输入元素,由指定的分隔符分隔,具有指定的前缀和后缀
    
    Stream<String> language = Stream.of("java", "php","java");
    String joining = language.collect(Collectors.joining());
    System.out.println(joining);//javaphpjava
    
    Stream<String> language1 = Stream.of("java", "php","java");
    String joining1 = language1.collect(Collectors.joining(","));
    System.out.println(joining1);//java,php,java
    
    Stream<String> language2 = Stream.of("java", "php","java");
    String joining2 = language2.collect(Collectors.joining(",", "[", "]"));
    System.out.println(joining2);//[java,php,java]
    

    collectingAndThen

    对Collector执行多次加工转换

    Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)Collector执行多次加工转换
    
    Stream<String> language = Stream.of("java", "php","java");
    String collectingAndThen = language.collect(Collectors.collectingAndThen(Collectors.joining(","), String::toUpperCase));
    System.out.println(collectingAndThen);//JAVA,PHP,JAVA
    

    groupingBy

    对元素分组

    Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)
    对类型T输入元素执行“分组”操作,符合条件的元素将组成一个 List 映射到以T为key 的 MapCollector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)
    对类型T输入元素执行“分组”操作,符合条件的元素将组成一个 集合 映射到以T为key 的 Map 中,downstream指定返回集合类型
    
    Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)
    对类型T输入元素执行“分组”操作,符合条件的元素将组成一个 集合 映射到以T为key 的 mapFactory新生成的map 中,downstream指定返回集合类型
    
    Stream<String> language = Stream.of("java", "php","java");
    Map<Integer, List<String>> map = language.collect(Collectors.groupingBy(String::length));
    System.out.println(map);//{3=[php], 4=[java, java]}
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Map<Integer, Set<String>> map2 = language2.collect(Collectors.groupingBy(String::length, Collectors.toSet()));
    System.out.println(map2);//{3=[php], 4=[java]}
    
    Stream<String> language3 = Stream.of("java", "php","java");
    LinkedHashMap<Integer, Map<String, Integer>> map3 = language3.collect(Collectors.groupingBy(String::length, LinkedHashMap::new, Collectors.toMap(o -> o, o -> o.length(), (o1, o2) ->  o1)));
    System.out.println(map3);//{4={java=4}, 3={php=3}}
    

    groupingByConcurrent

    分组后返回的是一个并发集合

    Collector<T, ?, ConcurrentMap<K, List<T>>> groupingByConcurrent(Function<? super T, ? extends K> classifier)
    对类型T输入元素执行“分组”操作,符合条件的元素将组成一个 List 映射到以T为key 的 并发MapCollector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)
    对类型T输入元素执行“分组”操作,符合条件的元素将组成一个 集合 映射到以T为key 的 并发Map 中,downstream指定返回集合类型
    
    Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)
    对类型T输入元素执行“分组”操作,符合条件的元素将组成一个 集合 映射到以T为key 的 mapFactory新生成的并发map 中,downstream指定返回集合类型
    
    Stream<String> language = Stream.of("java", "php","java");
    Map<Integer, List<String>> map = language.collect(Collectors.groupingByConcurrent(String::length));
    System.out.println(map);//{3=[php], 4=[java, java]}
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Map<Integer, Set<String>> map2 = language2.collect(Collectors.groupingByConcurrent(String::length, Collectors.toSet()));
    System.out.println(map2);//{3=[php], 4=[java]}
    
    Stream<String> language3 = Stream.of("java", "php","java");
    ConcurrentHashMap<Integer, Map<String, Integer>> map3 = language3.collect(Collectors.groupingByConcurrent(String::length, ConcurrentHashMap::new, Collectors.toMap(o -> o, o -> o.length(), (o1, o2) ->  o1)));
    System.out.println(map3);//{3={php=3}, 4={java=4}}
    

    partitioningBy

    Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate)
    根据Predicate对输入元素进行判断分区,并将它们组织成Map<Boolean, List<T>>
    
    Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream)
    根据Predicate对输入元素进行判断分区,并将它们组织成Map<Boolean, ?<T>>,downstream指定返回集合类型
    
    Stream<String> language = Stream.of("java", "php","java");
    Map<Boolean, List<String>> map = language.collect(Collectors.partitioningBy(o -> o.length() > 3));
    System.out.println(map);//{false=[php], true=[java, java]}
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Map<Boolean, Set<String>> map2 = language2.collect(Collectors.partitioningBy(o -> o.length() > 3, Collectors.toSet()));
    System.out.println(map2);//{false=[php], true=[java]}
    

    counting

    Collector<T, ?, Long> counting()
    计算输入元素的数量。 如果不存在元素,则结果为 0
    Stream<String> language = Stream.of("java", "php","java");
    Long count = language.collect(Collectors.counting());
    System.out.println(count);//3
    

    Stream.count() 实现相同功能

    Stream<String> language = Stream.of("java", "php","java");
    Long count = language.count();
    System.out.println(count);//3
    

    maxBy

    Collector<T, ?, Optional<T>> maxBy(Comparator<? super T> comparator)
    根据comparato比较后返回最大元素的Optional<T>
    
    Stream<String> language = Stream.of("java", "php","java");
    Optional<String> maxObj = language.collect(Collectors.maxBy(Comparator.comparingInt(String::length)));
    System.out.println(maxObj.get());//java
    

    Stream.max() 实现相同功能

    Stream<String> language = Stream.of("java", "php","java");
    Optional<String> max = language.max(Comparator.comparingInt(String::length));
    System.out.println(max.get());//java
    

    minBy

    Collector<T, ?, Optional<T>> minBy(Comparator<? super T> comparator)
    根据comparato比较后返回最小元素的Optional<T>
    
    Stream<String> language = Stream.of("java", "php","java");
    Optional<String> maxObj = language.collect(Collectors.minBy(Comparator.comparingInt(String::length)));
    System.out.println(maxObj.get());//php
    

    Stream.min() 实现相同功能

    Stream<String> language = Stream.of("java", "php","java");
    Optional<String> max = language.min(Comparator.comparingInt(String::length));
    System.out.println(max.get());//php
    

    summingXXX

    Collector<T, ?, Double> summingDouble(ToDoubleFunction<? super T> mapper)
    求输入元素的Double类型数值函数的总和
    Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper)
    求输入元素的Integer类型数值函数的总和
    Collector<T, ?, Long> summingLong(ToLongFunction<? super T> mapper)
    求输入元素的Long类型数值函数的总和
    
    Stream<String> language = Stream.of("java", "php","java");
    Double sumDouble = language.collect(Collectors.summingDouble(String::length));
    System.out.println(sumDouble);//11.0
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Integer sumInt = language2.collect(Collectors.summingInt(String::length));
    System.out.println(sumInt);//11
    
    Stream<String> language3 = Stream.of("java", "php","java");
    Long sumLong = language3.collect(Collectors.summingLong(String::length));
    System.out.println(sumLong);//11
    

    Stream.sum() 实现相同功能

    当Stream的类似是数字时,可以用Stream.sum()实现相同功能

    DoubleStream language = DoubleStream.of(4, 3, 4);
    double sumDouble = language.sum();
    System.out.println(sumDouble);//11.0
    
    IntStream language2 = IntStream.of(4, 3, 4);
    Integer sumInt = language2.sum();
    System.out.println(sumInt);//11
    
    LongStream language3 = LongStream.of(4, 3, 4);
    Long sumLong = language3.sum();
    System.out.println(sumLong);//11
    

    summarizingXXX

    汇总统计

    Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper)Double类型数值函数汇总统计,包含了 总数,总和,最小值,最大值,平均值 五个指标。
    
    Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)Integer类型数值函数汇总统计,包含了 总数,总和,最小值,最大值,平均值 五个指标。
    
    Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper)Long类型数值函数汇总统计,包含了 总数,总和,最小值,最大值,平均值 五个指标。
    
    Stream<String> language = Stream.of("java", "php","java");
    DoubleSummaryStatistics doubleSummaryStatistics = language.collect(Collectors.summarizingDouble(String::length));
    System.out.println(doubleSummaryStatistics);//DoubleSummaryStatistics{count=3, sum=11.000000, min=3.000000, average=3.666667, max=4.000000}
    
    Stream<String> language2 = Stream.of("java", "php","java");
    IntSummaryStatistics intSummaryStatistics = language2.collect(Collectors.summarizingInt(String::length));
    System.out.println(intSummaryStatistics);//IntSummaryStatistics{count=3, sum=11, min=3, average=3.666667, max=4}
    
    Stream<String> language3 = Stream.of("java", "php","java");
    LongSummaryStatistics longSummaryStatistics = language3.collect(Collectors.summarizingLong(String::length));
    System.out.println(longSummaryStatistics);//LongSummaryStatistics{count=3, sum=11, min=3, average=3.666667, max=4}
    

    mapping

    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream)
    先对元素使用 mapper 进行再加工操作,然后用另一个downstream 归纳
    
    Stream<String> language = Stream.of("java", "php","java");
    List<String> list = language.collect(Collectors.mapping(s -> s.substring(1), Collectors.toList()));
    System.out.println(list);//[ava, hp, ava]
    

    Stream.map 实现相同功能

    Stream<String> language2 = Stream.of("java", "php","java");
    List<String> list2 = language2.map(s -> s.substring(1)).collect(Collectors.toList());
    System.out.println(list2);//[ava, hp, ava]
    

    reducing

    Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op)
    根据op比较器来比较大小并分别返回最大值或者最小值,可能拿不到结果
    
    Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op)
    根据op比较器来比较大小并分别返回最大值或者最小值,identity为基准值,基准值也参与比较,没有结果时返回基准值,否则返回比较结果
    
    Collector<T, ?, U> reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op)
    先对元素进行mapper映射处理,再根据op比较器来比较大小并分别返回最大值或者最小值,identity为基准值,基准值也参与比较,没有结果时返回基准值,否则返回比较结果
    
    Stream<String> language = Stream.of("java", "php","java");
    Comparator<String> comparing = Comparator.comparing(String::length);
    Optional<String> obj = language.collect(Collectors.reducing(BinaryOperator.minBy(comparing)));
    System.out.println(obj);//Optional[php]
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Comparator<String> comparing2 = Comparator.comparing(String::length);
    String objStr = language2.collect(Collectors.reducing("androd", BinaryOperator.maxBy(comparing2)));
    System.out.println(objStr);//androd
    
    Stream<String> language3 = Stream.of("java", "php","java");
    Function<String, String> mapper = str -> {return str.substring(1);};
    Comparator<String> comparing3 = Comparator.comparing(String::length);
    String objStr2 = language3.collect(Collectors.reducing("androd", mapper, BinaryOperator.maxBy(comparing3)));
    System.out.println(objStr2);//androd
    

    Stream.reduce 实现相同功能

    Stream<String> language = Stream.of("java", "php","java");
    Comparator<String> comparing = Comparator.comparing(String::length);
    Optional<String> obj = language.reduce(BinaryOperator.minBy(comparing));
    System.out.println(obj);//Optional[php]
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Comparator<String> comparing2 = Comparator.comparing(String::length);
    String objStr = language2.reduce("androd", BinaryOperator.maxBy(comparing2));
    System.out.println(objStr);//androd
    
    Stream<String> language3 = Stream.of("java", "php","java");
    BiFunction<String, String, String> mapper = (str1, str2) -> { return str1.length()>str2.length()? str1:str2; };
    Comparator<String> comparing3 = Comparator.comparing(String::length);
    //第三个参数BinaryOperator.minBy(comparing3)无效,作用是合并各个流结果,故在parallelStream时才生效
    String objStr2 = language3.reduce("androd", mapper, BinaryOperator.minBy(comparing3));
    System.out.println(objStr2);//androd
    

    averagingDouble

    Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper)
    对元素进行Double类型数值函数映射处理后,求拼接值
    
    Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper)
    对元素进行Int类型数值函数映射处理后,求拼接值
    
    Collector<T, ?, Double> averagingLong(ToLongFunction<? super T> mapper)
    对元素进行Long类型数值函数映射处理后,求拼接值
    
    Stream<String> language = Stream.of("java", "php","java");
    Double averagingDouble = language.collect(Collectors.averagingDouble(String::length));
    System.out.println(averagingDouble);//3.6666666666666665
    
    Stream<String> language2 = Stream.of("java", "php","java");
    Double averagingInt2 = language2.collect(Collectors.averagingInt(String::length));
    System.out.println(averagingInt2);//3.6666666666666665
    
    Stream<String> language3 = Stream.of("java", "php","java");
    Double averagingLong3 = language3.collect(Collectors.averagingLong(String::length));
    System.out.println(averagingLong3);//3.6666666666666665
    

    Stream.average() 实现相同功能

    当Stream的类似是数字时,可以用Stream.sum()实现相同功能

    DoubleStream language = DoubleStream.of(4, 3, 4);
    OptionalDouble sumDouble = language.average();
    System.out.println(sumDouble.getAsDouble());//3.6666666666666665
    
    IntStream language2 = IntStream.of(4, 3, 4);
    OptionalDouble sumInt = language2.average();
    System.out.println(sumInt.getAsDouble());//3.6666666666666665
    
    LongStream language3 = LongStream.of(4, 3, 4);
    OptionalDouble sumLong = language3.average();
    System.out.println(sumLong.getAsDouble());//3.6666666666666665
    
    展开全文
  • JDK8中Stream 中Collectors 规约处理 Collectors常用方法详解 List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","","11","22","33", "jkl"); 一般输出指定集合类型 strings.stream...

    JDK8中Stream 中Collectors 规约处理

    Collectors常用方法详解

     List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","","11","22","33", "jkl");
    
    

    forEachOrdered 和forEach 打印集合

    forEachOrdered 需要和parallel、parallelStream 一起搭配食用,并行流下才能保证顺序性

         //forEach 其实前就已经见过了,对每个数据遍历迭代
            list.stream().unordered();
            //forEachOrdered 适用用于并行流的情况下进行迭代,能保证迭代的有序性
            //这里通过并行的方式输出数字
            System.out.println("---------- 并行流下 forEachOrdered 保证list顺序 ----------");
            list.stream().parallel().forEachOrdered(System.out::println);
            list.parallelStream().forEachOrdered(System.out::println);
            //并行流下 不保证list顺序  每次输出顺序不一致
            System.out.println("---------- 并行流下 forEach 不保证list顺序 ----------");
            list.stream().parallel().forEach(System.out::println);
            System.out.println("---------- 并行流下 forEach 不保证list顺序 ----------");
            list.stream().parallel().forEach(System.out::println);
            list.parallelStream().forEach(System.out::println);
    

    一般输出指定集合类型

       strings.stream().collect(Collectors.toList());
            strings.stream().collect(Collectors.toSet());
            //重复key 会抛异常
    //        strings.stream().collect(Collectors.toConcurrentMap(String::toString,String->String));
            //可以使用第三个参数根据逻辑获取value
            strings.stream().collect(Collectors.toConcurrentMap(String::toString,String->String,(val1,val2)->{
                if (val1.equals(val2)){
                    return val1;
                }else {
                    return val2;
                }
            }));
            //toCollection 可以指定集合
            strings.stream().collect(Collectors.toCollection(LinkedList::new));
            strings.stream().collect(Collectors.toCollection(LinkedHashSet::new));
    
    

    filter过滤

    过滤指定条件
    可以使用lambda 表达式的语法写法 、也可以指定类型写

             System.out.println(strings.parallelStream().filter(x -> x.length() > 1).collect(Collectors.toList()));
            //Predicate 类型 过滤相同
            System.out.println(strings.stream().filter(Predicate.isEqual("abc").or(Predicate.isEqual("11"))).collect(Collectors.toList()));
            System.out.println(strings.stream().filter(Predicate.isEqual("abc").and(Predicate.isEqual("11"))).collect(Collectors.toList()));
    
    

    输出

    [abc, bc, efg, abcd, 11, 22, 33, jkl]
    [abc, 11]
    []
    

    joining方法

      //默认拼接
            System.out.println(strings.parallelStream().filter(x -> x.length() > 1).collect(Collectors.joining()));
            //没有后缀
            System.out.println(strings.parallelStream().filter(x -> x.length() > 1).collect(Collectors.joining(",")));
            //前后缀
            System.out.println(strings.parallelStream().filter(x -> x.length() > 1).collect(Collectors.joining("","<",">")));
    
    
    

    输出

    abcbcefgabcd112233jkl
    abc,bc,efg,abcd,11,22,33,jkl
    <abcbcefgabcd112233jkl>
    
    
    统计信息

    IntSummaryStatistics 和 LongSummaryStatistics 和 DoubleSummaryStatistics

    这三个分别对应 三个方法 分别求不同类型的平均数,最大,最大小 数量 总数 求和
    在这里插入图片描述

    
        List<Integer> arrays1 = Arrays.asList(1, 2, 22, 11, 11,22,78,99,0, 145,54);
    
           System.out.println(" ----  DoubleSummaryStatistics ----- ");
            DoubleSummaryStatistics doubleSummaryStatistics = arrays1.stream().collect(
                    Collectors.summarizingDouble(Integer::intValue));
    
            System.out.println(doubleSummaryStatistics.getSum());
            System.out.println(doubleSummaryStatistics.getMax());
            System.out.println(doubleSummaryStatistics.getMin());
            System.out.println(doubleSummaryStatistics.getAverage());
            System.out.println(doubleSummaryStatistics.getCount());
    
            System.out.println(" ----  IntSummaryStatistics ----- ");
            IntSummaryStatistics intSummaryStatistics = arrays1.stream().collect(Collectors.summarizingInt(Integer::intValue));
            System.out.println(intSummaryStatistics.getSum());
            System.out.println(intSummaryStatistics.getMax());
            System.out.println(intSummaryStatistics.getMin());
            System.out.println(intSummaryStatistics.getAverage());
            System.out.println(intSummaryStatistics.getCount());
    
            System.out.println(" ----  LongSummaryStatistics ----- ");
            LongSummaryStatistics longSummaryStatistics = arrays1.stream().collect(Collectors.summarizingLong(Integer::intValue));
    
            System.out.println(longSummaryStatistics.getSum());
            System.out.println(longSummaryStatistics.getMax());
            System.out.println(longSummaryStatistics.getMin());
            System.out.println(longSummaryStatistics.getAverage());
            System.out.println(longSummaryStatistics.getCount());
    

    输出

     ----  DoubleSummaryStatistics ----- 
    445.0
    145.0
    0.0
    40.45454545454545
    11
     ----  IntSummaryStatistics ----- 
    445
    145
    0
    40.45454545454545
    11
     ----  LongSummaryStatistics ----- 
    445
    145
    0
    40.45454545454545
    11
    
    

    而averagingInt/averagingLong/averagingDouble 三个方法 ,分别有对应彼此的Double类型求平均数

      System.out.println(" ----  获取平均值的 Collectors.averaging xxxx  几个方法返回值都是Double类型。 ----- ");
            Double aDouble = arrays1.stream().collect(Collectors.averagingDouble(Integer::intValue));
            System.out.println(aDouble);
            Double integer = arrays1.stream().collect(Collectors.averagingInt(Integer::intValue));
            System.out.println(integer);
            Double collect1 = arrays1.stream().collect(Collectors.averagingLong(Integer::intValue));
            System.out.println(collect1);
    

    输出

     ----  获取平均值的 Collectors.averaging xxxx  几个方法返回值都是Double类型。 ----- 
    40.45454545454545
    40.45454545454545
    40.45454545454545
    
    partitioningBy 分组 和 groupingBy分组

    groupingBy分组,partitioningBy分组之后还可以根据条件再过滤

    groupingBy方法

    构造函数

    public static <T, K, A, D>
    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,// 分组结果map的key的生成
                                          Collector<? super T, A, D> downstream) {//分组结果map的value的生成
    }
    
    public static <T, K, D, A, M extends Map<K, D>>
        Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,// 分组结果map的key的生成
                                      Supplier<M> mapFactory,// 分组结果map的生成
                                      Collector<? super T, A, D> downstream) {//分组结果map的value的生成
    }
    

    实例

     System.out.println("------ groupingBy方法 默认分组 -------");
            //默认返回hashmap
            Map<Boolean, List<String>> collect3 = strings.stream().collect(Collectors.groupingBy(x -> x.length() > 1));
            System.out.println(collect3);
            //两个参数 传递还是 Collector 也就是说还可以 使用 Collector继续操作
            //这里使用统计数量
            Map<Boolean, Long> collect4 = strings.stream().collect(Collectors.groupingBy(x -> x.length() > 1, Collectors.counting()));
            System.out.println(collect4);
            //这里继续分组
            Map<Boolean, Map<Boolean, List<String>>> collect5 = strings.stream().collect(Collectors.groupingBy(x -> x.length() > 1, Collectors.groupingBy(x -> x.length() > 4)));
            System.out.println(collect5);
    
            //三个参数,  第二个指定返回类型
            TreeMap<Boolean, Map<Boolean, List<String>>> collect6 = strings.stream().collect(Collectors.groupingBy(x -> x.length() > 1, TreeMap::new, Collectors.groupingBy(x -> x.length() > 2)));
            System.out.println(collect6);
    

    输出

    ------ groupingBy方法 默认分组 -------
    {false=[, ], true=[abc, bc, efg, abcd, 11, 22, 33, jkl]}
    {false=2, true=8}
    {false={false=[, ]}, true={false=[abc, bc, efg, abcd, 11, 22, 33, jkl]}}
    {false={false=[, ]}, true={false=[bc, 11, 22, 33], true=[abc, efg, abcd, jkl]}}
    
    partitioningBy

    构造

    public static <T>
        Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
            return partitioningBy(predicate, toList());
        }
    

    partitioningBy和groupingBy 最大的区别是partitioningBy只能由于条件分组,不能用于值分组,而 groupingBy 即可以值分组 也可以条件分组

    可以看到编译首先过不去
    在这里插入图片描述
    可以看到编译器提示 必须是布尔类型
    在这里插入图片描述

           // groupingBy 根据条件分组 满足的和不满足的都分组  之后还可以分组,但是不能再过滤了
            Map<Boolean, List<Integer>> collect2 = arrays1.stream().collect(Collectors.groupingBy(x -> x.intValue() > 2));
            //大于2的分为一组 每个分组
            System.out.println(collect2);
    
    
            // partitioningBy 根据条件分组 满足的和不满足的都分组  之后还可以根据条件再进行过滤
            Comparator<Integer> comparing = Comparator.comparing(Integer::intValue);
            Map<Boolean, Optional<Integer>> booleanListMap = arrays1.stream().collect(Collectors.partitioningBy(x -> x.intValue() > 2,Collectors.reducing(BinaryOperator.maxBy(comparing))));
            //大于2和不大于2的分组 共2组
            System.out.println(booleanListMap);
    

    输出

    {false=[1, 2, 0], true=[22, 11, 11, 22, 78, 99, 145, 54]}
    {false=Optional[2], true=Optional[145]}  	
    {false=3, true=8}  // 统计出数量
    
    

    counting方法

    统计总数 相当于 mapInt 之后的sum()方法

            Map<Boolean, Long> booleanIntegerMap1 = arrays1.stream().collect(Collectors.groupingBy(x -> x.intValue() > 2,Collectors.counting()));
    

    相当于

    arrays1.stream().mapToInt(Integer::intValue).count();
    

    toMap方法

    toMap 将集合转为map类型

    构造

    public static <T, K, U> Collector<T, ?, Map<K,U>> 
        toMap(Function<? super T, ? extends K> keyMapper,
              Function<? super T, ? extends U> valueMapper)
    

    在上面输出指定集合类型中可以看到 相同key的话会报错,这里会用构造进行处理相同的Key,去选择value值

            //todo 2个参数
            // todo -------------------- 相同的存在相同的key会报错
            /*Map<String, String> collect10 = strings.stream().collect(Collectors.toMap(
                    String::toString,  //key
                    Function.identity() // 第二个参数 是value  也可以是:  String->String
            ));
    
            System.out.println(collect10);
    
            //也可以写成
            Map<String, String> collect11 = strings.stream().collect(Collectors.toMap(
                    String::toString,  //key
                    String->String
            ));
            System.out.println(collect11);
    
            //也可以写成
            Map<String, String> collect12 = strings.stream().collect(Collectors.toMap(
                    String::toString,  //key
                    String->String
            ));
    
            //相同的存在相同的key会报错,
            System.out.println(collect12);*/
            // todo -------------------- 相同的存在相同的key会报错
    
    

    相同Key冲突 处理,以及指定返回map

    构造

    
    public static <T, K, U, M extends Map<K, U>>
    Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction,
                                Supplier<M> mapSupplier) {
    
    

    实例:

            // 三个参数 构造方法 , 第三个参数 如果有冲突的key  自定义选择value值返回  最后一个mapSupplier参数指定返回Map类型
    
            //如果有重复的key 比较value 值选择返回key的value值
            Map<String, String> collect = strings.stream().collect(Collectors.toMap(
                    String::toString,  //key
                    Function.identity(), // 第二个参数 是value  也可以是:  String->String
                    (xValue,yValue)->{  // 第三个参数 如果有冲突的key  自定义选择value值返回
                        if (xValue.length() > yValue.length()) { // 这里根据逻辑选择相同Key的value值
                            return xValue;
                        }else {
                            return yValue;
                        }
                    },
                    //  第四个参数指定返回map构造器
                    ()->{
    //                    return new HashMap<>();
                        return new TreeMap<>();
                    }));
    
    
    
            System.out.println(collect);
    

    reduce 表示对元素里值做运算

    reducing及其重载形式,maxBy,minBy
    reducing表示对steam里的元素做运算,最终等到一个值。
    identity:初值,设置一个steam元素与外部比较的一个初始值。
    mapper: 将stream内部类型映射为U类型的方法
    BinaryOperator:op两个U类型值合并运算的方法

    在这里插入图片描述
    上面两个是一个类型api 是否有初始值,第二是比较的函数

     
            BinaryOperator<User> tBinaryOperator = BinaryOperator.maxBy(Comparator.comparing(User::getAge));
            //传一个初始值 返回符合条件的值
            User collect14 = list.stream().collect(Collectors.reducing(new User(), tBinaryOperator));
            System.out.println(collect14);
    
            User collect15 = list.stream().collect(Collectors.reducing(tBinaryOperator)).get();
            System.out.println(collect15);
    
    
            //将stream内部类型转化成合并运算的对象(User)  然后再根据  tBinaryOperator 获取符合条件的值
            User collect16 = list.stream().collect(Collectors.reducing(new User(), x->{
                x.setAge(x.getAge() + 1);
                return x;
            }, tBinaryOperator));
            System.out.println(collect16);
    

    输出

    User{name='老王', age=29, classic='部门2', manager='Java'}
    User{name='老王', age=29, classic='部门2', manager='Java'}
    User{name='老王', age=30, classic='部门2', manager='Java'}
    

    maxBy/minBy方法

    和reduce连起来使用,对值进行运算返回一个值

       BinaryOperator<Integer> maxBy = BinaryOperator.maxBy(Comparator.comparing(Integer::intValue));
            BinaryOperator<Integer> minBy = BinaryOperator.minBy(Comparator.comparing(Integer::intValue));
    
            //   BinaryOperator 构造方法 public static <T> Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op)
            Map<Boolean, Optional<Integer>> max = arrays1.stream().collect(Collectors.groupingBy(x -> x.intValue() > 1, Collectors.reducing(maxBy)));
            Map<Boolean, Optional<Integer>> min = arrays1.stream().collect(Collectors.groupingBy(x -> x.intValue() > 1, Collectors.reducing(minBy)));
            System.out.println(max);
            System.out.println(min);
    
    

    mapping方法

    mapping方法用于对Stream中元素的某个具体属性做进一步的映射处理,一般是和其他方法一起组合使用

      //按照年龄分组,然后,拼接
            Map<Integer, String> collect10 = list.stream().collect(Collectors.groupingBy(User::getAge,
                    Collectors.mapping(User::getName, Collectors.joining(",")))
            );
    
            System.out.println(collect10);
    
    
            //根据年龄分组 然后根据输出名字集合  等于 "先分组 再map属性"
            Map<Integer, List<String>> collect11 = list.stream().collect(Collectors.groupingBy(User::getAge,
                    Collectors.mapping(User::getName, Collectors.toList())));
    
            System.out.println(collect11);
    
            //相当于 下面 listMap
            //先分组
            Map<Integer, List<User>> collect12 = list.stream().collect(Collectors.groupingBy(User::getAge));
            Map<Integer, List<String>> listMap = new HashMap<>();
            //再拿到List 去Map属性
            collect12.forEach((key,list)->{
                listMap.put(key,list.stream().map(User::getName).collect(Collectors.toList()));
            });
    
        }
    
    
        public static final List<User> list = Arrays.asList(
                new User("小王",18,"1班","学生"),
                new User("小涨",23,"部门1","Java开发"),
                new User("小李",23,"部门2","golang开发"),
                new User("小吕",18,"2班","学生"),
                new User("老王",29,"部门2","Java")
                );
    }
    
    class User{
        private String name;
        private int age;
        private String classic;
        private String manager;
    
        public User() {
        }
    
        public User(String name, int age, String classic, String manager) {
            this.name = name;
            this.age = age;
            this.classic = classic;
            this.manager = manager;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getClassic() {
            return classic;
        }
    
        public void setClassic(String classic) {
            this.classic = classic;
        }
    
        public String getManager() {
            return manager;
        }
    
        public void setManager(String manager) {
            this.manager = manager;
        }
    }
    
     @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", classic='" + classic + '\'' +
                    ", manager='" + manager + '\'' +
                    '}';
        }
    
    

    输出

    {18=小王,小吕, 23=小涨,小李, 29=老王}
    {18=[小王, 小吕], 23=[小涨, 小李], 29=[老王]}
    {18=[小王, 小吕], 23=[小涨, 小李], 29=[老王]}
    

    collectingAndThen方法

        // 该方法接收两个参数,表示在第一个参数执行基础上,再执行第二个参数对应的函数表达式,
            Double aDouble1 = arrays2.stream().collect(Collectors.averagingDouble(Integer::intValue));
            Double aDouble2 = arrays2.stream().collect(Collectors.collectingAndThen(Collectors.averagingDouble(Integer::intValue), s -> s * 2));
            System.out.println(aDouble1);//40.45454545454545
            System.out.println(aDouble2);//80.9090909090909
    
    
            // 生成不可变List
            List<Integer> unmodifiableList = arrays2.stream().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
            System.out.println(unmodifiableList.size());
            // 不可变list
            // unmodifiableList.add(1); // todo java.util.Collections$UnmodifiableCollection.add
    
    
    

    groupingByConcurrent方法

    groupingByConcurrent方法 见名知其意 线程安全的
    groupBy线程不安全

     // 返回的Map类型是ConcurrentHashMap,用法和groupingBy方法是类似的
            Map<Boolean, List<String>> collect8 = strings.stream().collect(Collectors.groupingBy(x -> x.length() > 1));
            System.out.println(collect8);
            ConcurrentMap<Boolean, ConcurrentMap<Boolean, List<String>>> collect9 = strings.stream().collect(Collectors.groupingByConcurrent(x -> x.length() > 1, Collectors.groupingByConcurrent(x -> x.length() > 2)));
            System.out.println(collect9);
            ConcurrentMap<Object, ConcurrentMap<Object, List<String>>> collect7 = strings.stream().collect(Collectors.groupingByConcurrent(x -> x.length() > 1, ConcurrentHashMap::new, Collectors.groupingByConcurrent(x -> x.length() > 2)));
            System.out.println(collect7);
    
    展开全文
  • 相思相见知何日?此时此夜难为情。返回List集合: toList()用于将元素累积到List集合中。它将创建一个新List集合(不会更改当前集合)。List integers = ... x*x).collect(Collectors.toList());// output: [1,4,9...
  • 一、概述Collector是专门用来作为Stream的collect方法的参数的。public interface Stream extends BaseStream>...}而Collectors是作为生产具体Collector的工具类。二、CollectorCollector主要包含五个参数...
  • Java8中Collectors详解

    万次阅读 多人点赞 2019-08-09 22:35:00
    例如,可以调整toList()收集器,以始终生成一个不可变的列表: List<Student> studentList = menu.stream().collect( Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));...
  • java8中 Collectors.groupingBy用法

    千次阅读 2021-04-01 17:33:11
    Collectors.groupingBy根据一个或多个属性对集合中的项目进行分组 1、数据准备: public Product(Long id, Integer num, BigDecimal price, String name, String category) { this.id = id; this.num = num; ...
  • 玩转Java 8 Stream(Collectors收集器篇)

    千次阅读 2020-06-22 09:25:50
    之前的文章中也提到了,Stream 的核心在于Collectors,即对处理后的数据进行收集。Collectors 提供了非常多且强大的API,可以将最终的数据收集成List、Set、Map,甚至是更复杂的结构(这三者的嵌套组合)。 ...
  • 昨天在 Collection移除元素操作 相关的文章中提到了 Collectors 。相信很多同学对这个比较感兴趣,那我们今天就来研究一下 Collectors 。2. Collectors 的作用Collectors 是 Java 8 加入的操作类,位于 java.util....
  • java8中Collectors的方法使用实例

    千次阅读 2019-09-08 20:19:56
    java8中Collectors的方法: toCollection toList toSet toMap joining mapping/flatMapping filtering collectingAndThen counting minBy maxBy summingInt/summingLong/summingDouble averagingInt/...
  • = null).collect(Collectors.groupingBy(Student::getGender,Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Student::getScore)),Optional::get)));//计算男女中最低的分数Mapcollect10 = ...
  • Java 8 Collectors分组及Collectors.mapping使用案例 今天学习的考核中,导师给出了一个需求: 利用java8 lambdas语言特性处理如下java集合对象, 为了方便描述对象用json表示为[{id:1,name:null},{id:1,name:”...
  • Collector Collector是专门用来作为Stream的collect方法的参数的。 public interface Stream<T> extends BaseStream<...而Collectors是作为生产具体Collector的工具类。 Collector主要包含五个.
  • java8 Collectors 常用方法

    千次阅读 2019-12-23 16:03:44
    Map, Optional<User>> collect2 = users.stream().collect(Collectors.groupingBy(User::getAge, Collectors.minBy(Comparator.comparing(User::getId)))); System.out.println("分组后取id最大值"); System.out...
  • Java 8 新特性|Collectors.joining() 详解

    千次阅读 2021-04-22 17:53:26
    方法定义Java 8 流 ( stream ) 收集器 ( Collectors ) 中的joining()方法会返回一个Collectors实例,方便在流收集器上的链式操作。Co...
  • Java8的 Stream 之Collectors收集器

    千次阅读 2020-05-26 11:25:09
    Stream 的核心在于Collectors,即对处理后的数据进行收集。Collectors 提供了非常多且强大的API,可以将最终的数据收集成List、Set、Map,甚至是更复杂的结构(这三者的嵌套组合)。 Collectors 提供了很多API,有很...
  • Java8 Stream(11)Collectors 案例详解一、获得对象中某1个属性集合1. toList 获取id的List集合2. toSet 获取gender的Set集合二、List 转 Map1. toMap 将List的值转成 id -> name的Map2. 解决key重复后异常三、...
  • 作者:liteskywww.jianshu.com/p/6ee7e4cd5314之前的文章中也提到了,Stream 的核心在于Collectors,即对处理后的数据进行收集。Collec...
  • 返回List集合: toList() 用于将元素累积到List集合中。它将创建一个新List集合(在不... x*x).collect(Collectors.toList()); 返回Set集合: toSet() 用于将元素累积到Set集合中。会删除重复元素。 List<Intege

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,980
精华内容 26,792
关键字:

collectors

友情链接: spectural_clustering.zip