java 8 Collectors(收集器)API简单使用

Collectors API介绍

java.util.stream.Collectors类为我们提供了丰富的对流的操作,接下来我们来看看这些API的具体功能

  • averagingDouble(ToDoubleFunction<? super T> mapper)
        /*
         * averagingDouble/Int/Long
         * 汇总求出平均值
         */
        public double averagingDoubleTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(averagingDouble(student -> student.getHeight()));
        }   
  • collectingAndThen(Collector
        /*
         * collectingAndThen 将收集来的结果进行而外的转换
         * 本例中将收集的结果放入不可变List中。
         */
        public List<String> collectingAndThenTest(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .map(student -> student.getName())
                    .collect(collectingAndThen(toList(), Collections::unmodifiableList));
        }
  • counting()
        /*
         * 简单的计数器,简单的计算流元素。
         */
        public long countingTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(counting());
        }
  • groupingBy(Function<? super T,? extends K> classifier)
        /*
         * 通过省份将学生分组到List中。
         */
        public Map<String, List<Student>> groupingByToList(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingBy(Student::getFrom));
        }
  • groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)
        /*
         * 通过省份将学生分组到Set中。
         */
        public Map<String, Set<Student>> groupingByToSet(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingBy(Student::getFrom, toSet()));
        }
  • groupingBy(Function<? super T,? extends K> classifier, Supplier
        /*
         * 通过省份将学生分组到Set中。并返回一个TreeMap.
         */
        public Map<String, Set<Student>> groupingByToTreeMap(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingBy(Student::getFrom, TreeMap::new, toSet()));
        }
  • groupingByConcurrent(Function<? super T,? extends K> classifier)
        /*
         * 返回并发的Map
         */
        public Map<String, List<Student>> groupingByConcurrentTest(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingByConcurrent(Student::getFrom));
        }
  • groupingByConcurrent(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)
        /*
         * 返回并发的Map
         */
        public Map<String, Set<Student>> groupingByConcurrentToSet(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingByConcurrent(Student::getFrom, toSet()));
        }
  • groupingByConcurrent(Function<? super T,? extends K> classifier, Supplier
        /*
         * 返回并发的Map
         */
        public Map<String, Set<Student>> groupingByConcurrentToSkipMap(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingByConcurrent(Student::getFrom, ConcurrentSkipListMap::new, toSet()));
        }
  • joining()
        /*
         * 返回所有的学生的姓名
         */
        public String joiningTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .map(Student::getName)
                    .collect(joining());
        }
  • joining(CharSequence delimiter)
        /*
         * 返回所有的学生的姓名,姓名之间用逗号分割。
         */
        public String joiningDelimiter(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .map(Student::getName)
                    .collect(joining(", "));
        }
  • joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
        /*
         * 返回所有的学生的姓名,姓名之间用逗号分割,并放在中括号里边。
         */
        public String joiningDelimiterPreAndSuf(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .map(Student::getName)
                    .collect(joining(", ", "[", "]"));
        }
  • mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)
        /*
         * 以省份分组,并返回学生姓名的集合。
         */
        public Map<String, List<String>> mappingTest(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingBy(Student::getFrom, mapping(Student::getName, toList())));
        }
  • maxBy(Comparator<? super T> comparator)
        /**
         * 
         * @param students
         * @return
         * 返回身高最高的学生
         */
        public Student maxByTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(maxBy(Comparator.comparingDouble(Student::getHeight)))
                    .get();
        }
  • minBy(Comparator<? super T> comparator)
        /**
         * 
         * @param students
         * @return 返回体重最轻的学生。
         */
        public Student minByTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(minBy(Comparator.comparingDouble(Student::getWeight)))
                    .get();
        }
  • partitioningBy(Predicate<? super T> predicate)
        /**
         * 
         * @param students
         * @return
         * 根据Predicate将流分割,并将它们组织成一个 Map<Boolean, List<T>>返回。
         */
        public Map<Boolean, List<Student>> partitioningByTest(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(partitioningBy(student -> Constants.Province.SHANNXI.equals(student.getFrom())));
        }
  • partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)
        /**
         * 
         * @param students
         * @return
         * 根据Predicate将流分割,并将它们组织成一个 Map<Boolean, List<T>>返回。
         */
        public Map<Boolean, Set<Student>> partitioningByToSet(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(partitioningBy(student -> Constants.Province.SHANNXI.equals(student.getFrom()), toSet()));
        }
  • reducing(BinaryOperator
        /**
         * 
         * @param students
         * @return
         * 返回一个班级中每个省份的身高最高的学生。
         */
        public Map<String, Optional<Student>> reducingTest(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            Comparator<Student> byHeight = Comparator.comparing(Student::getHeight);
            return students.stream()
                .collect(groupingBy(Student::getFrom, reducing(BinaryOperator.maxBy(byHeight))));
        }
  • summarizingDouble(ToDoubleFunction<? super T> mapper)
        /**
         * summarizingDouble/Int/Long
         * @param students
         * @return DoubleSummaryStatistics
         * 用另一种方式来求学生的平均体重。
         */
        public Double summarizingDoubleTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(summarizingDouble(Student::getWeight))
                    .getAverage();
            
        }
  • summingDouble(ToDoubleFunction<? super T> mapper)
        /**
         * 求和,如果元素不存在,则结果为0.
         * @param students
         * @return
         * 求学生的平均身高
         */
        public double summingDoubleTest(List<Student> students) {
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(summingDouble(Student::getHeight)) / students.size();
        }
  • toCollection(Supplier
        /**
         * 
         * @param students
         * @return
         * 将元素放入制定的集合中
         */
        public List<String> toCollectionToList(List<Student> students){
            return students.stream()
                    .map(Student::getName)
                    .collect(toCollection(ArrayList::new));
        }
  • toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
        /**
         * 
         * @param students
         * @return
         * 获取学生的成绩
         */
        public Map<String, Map<String, Double>> toConcurrentMapTest(List<Student> students){
            return students.stream()
                    .collect(toConcurrentMap(Student::getName, Student::getScores));
        }
  • toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
        /**
         * 
         * @param students
         * @return
         */
        public Map<String, Date> toMapTest(List<Student> students){
            return students.stream()
                    .collect(toMap(Student::getName, Student::getBirthday));
        }

将收集器函数分组到 Collector 抽象中在语法上更简单,但实际收益来自您开始将收集器组合在一起时,比如您想要创建复杂的汇总结果。接下来我们来尝试将各种收集器组合起来看看。

  • 让我们看一个将各种收集器综合起来的例子
        /**
         * 
         * @param address
         * @return
         * @throws FileNotFoundException
         * 统计一篇文章的词频直方图。
         */
        public Map<String, Long> toMapForWord(String address) throws FileNotFoundException{
            Objects.requireNonNull(address, "The parameter cannot be empty");
            BufferedReader reader = null;
            Pattern whitespace = Pattern.compile("\\s+");
            try {
                reader = new BufferedReader(new FileReader(new File(address)));
                return reader.lines()
                        .flatMap(string -> whitespace.splitAsStream(string))
                        .collect(groupingBy(String::toLowerCase, counting()));
            } catch (Exception e) {
                // Error log
                return new HashMap<String, Long>();
            } finally {
                StreamUtils.close(reader);
            }
        }
  • 统计一个班级中每个省份身高最高的学生
        /**
         * 返回每个省份的最高学生的所有信息。
         * @param students
         * @return
         */
        public Map<String, Map<String, Optional<Student>>> accountMaxHeightByProvince(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(groupingBy(Student::getFrom,
                                groupingBy(Student::getName,
                                        maxBy(Comparator.comparingDouble(Student::getHeight)))));
        }
  • 先以性别分组然后再以省份分组,返回学生的平均身高。
        /**
         * 先以性别分组然后再以省份分组,返回学生的平均身高。
         * @param students
         * @return
         */
        public Map<Boolean, Map<String, Double>> averageHeightByProvince(List<Student> students){
            Objects.requireNonNull(students, "The parameter cannot be empty");
            return students.stream()
                    .collect(partitioningBy(student -> "M".equals(student.getGender()),
                                groupingBy(Student::getFrom, averagingDouble(Student::getHeight))));
        }
结束语

用例中所有使用到的代码可以在GitHub上下载。

参考文档

java.util.stream官方文档

猜你喜欢

转载自www.cnblogs.com/yuanbing1226/p/9005476.html
今日推荐