Collector和Collectors

在Stream中有一個名為collect終止操作,其函數(shù)聲明如下

 <R, A> R collect(Collector<? super T, A, R> collector);

這個操作的作用是將Stream中的T類型元素通過Collector 中的A類型的可變?nèi)萜?,最終reduce為R類型數(shù)據(jù)
而Collectors是Collecor的工具類,在Collectors里面實現(xiàn)了諸多有用的Collecor
通過上述的說明,你可能還是不太明白,那么舉一個小的例子:

 String []strArray={"hello","world"};
 List<String> strList=Arrays.stream(strArray).collect(Collectors.toList());

這個例子將String類型的Stream 通過collect函數(shù)收集為一個List類型

Collector

Collector是一個接口,其聲明如下:

Interface Collector<T,A,R>

其中的泛型含義如下:

  • T - Stream中包含的元素類型
  • A - 中間容器類型
  • R - 結果數(shù)據(jù)類型

A Collector 由四個函數(shù)配合工作:

這些函數(shù)的工作流程如下

     A a1 = supplier.get();
     accumulator.accept(a1, t1);
     accumulator.accept(a1, t2);
     R r1 = finisher.apply(a1);  // result without splitting

     A a2 = supplier.get();
     accumulator.accept(a2, t1);
     A a3 = supplier.get();
     accumulator.accept(a3, t2);
     R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting

Collectors

Collectors是對Collector的實現(xiàn),他包含了很多有用的reduce操作,比如將元素收集到集合之中,統(tǒng)計元素個數(shù),分組等操作

Collectors使用實例

package com.example.lambda;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CollectorsTest {
    static class Employee {
        private String name;
        private int age;
        private int salary;
        private String dept;

        Employee(String name, int age, int salary, String dept) {
            this.name = name;
            this.age = age;
            this.salary = salary;
            this.dept = dept;
        }

        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 int getSalary() {
            return salary;
        }

        public void setSalary(int salary) {
            this.salary = salary;
        }

        public String getDept() {
            return dept;
        }

        public void setDept(String dept) {
            this.dept = dept;
        }

        @Override
        public String toString() {
            return "Employee{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", salary=" + salary +
                    ", dept='" + dept + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {
        Employee e1 = new Employee("e1", 20, 8000, "BS");
        Employee e2 = new Employee("e2", 21, 7500, "BS");
        Employee e3 = new Employee("e3", 22, 7500, "CW");
        Employee e4 = new Employee("e4", 23, 10000, "CW");
        Employee e5 = new Employee("e5", 24, 15000, "IT");
        Employee e6 = new Employee("e6", 25, 16000, "IT");
        Employee e7 = new Employee("e7", 24, 17000, "IT");
        List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7);
        //找出工資最高的員工
        employees.stream().collect(Collectors.maxBy(Comparator.comparingInt(Employee::getSalary))).ifPresent(e -> {
            System.out.println("工資最高的員工是: " + e);
        });
        //員工的平均工資
        Double avgSalary = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("員工的平均工資為: " + avgSalary);
        //員工名單
        String empNames = employees.stream().map(Employee::getName).collect(Collectors.joining(",", "<", ">"));
        System.out.println("員工名單: " + empNames);

        //分組,先根據(jù)部門分組然后根據(jù)年齡分組
        Map<String, Map<Integer, List<Employee>>> groupMap = employees.stream().collect(Collectors.groupingBy(Employee::getDept, Collectors.groupingBy(Employee::getAge)));
        System.out.println("先根據(jù)部門分組然后根據(jù)年齡分組:" + groupMap);
        //各個部門的人數(shù)
        Map<String, Long> countMap = employees.stream().collect(Collectors.groupingBy(Employee::getDept, Collectors.counting()));
        System.out.println("各個部門的人數(shù):" + countMap);
    }
}

運行結果:

工資最高的員工是: Employee{name='e7', age=24, salary=17000, dept='IT'}
員工的平均工資為: 11571.42857142857
員工名單: <e1,e2,e3,e4,e5,e6,e7>
先根據(jù)部門分組然后根據(jù)年齡分組:{BS={20=[Employee{name='e1', age=20, salary=8000, dept='BS'}], 21=[Employee{name='e2', age=21, salary=7500, dept='BS'}]}, CW={22=[Employee{name='e3', age=22, salary=7500, dept='CW'}], 23=[Employee{name='e4', age=23, salary=10000, dept='CW'}]}, IT={24=[Employee{name='e5', age=24, salary=15000, dept='IT'}, Employee{name='e7', age=24, salary=17000, dept='IT'}], 25=[Employee{name='e6', age=25, salary=16000, dept='IT'}]}}
各個部門的人數(shù):{BS=2, CW=2, IT=3}

參考

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 1. Stream初體驗 我們先來看看Java里面是怎么定義Stream的: A sequence of elem...
    kechao8485閱讀 1,282評論 0 9
  • 原創(chuàng)文章,轉載請標注出處:《Java基礎系列-Collector和Collectors》 一、概述 Collect...
    唯一浩哥閱讀 46,981評論 4 51
  • Int Double Long 設置特定的stream類型, 提高性能,增加特定的函數(shù) 無存儲。stream不是一...
    patrick002閱讀 1,331評論 0 0
  • 原文地址: 深藍至尊 一. 流式處理簡介 在我接觸到java8流式處理的時候,我的第一感覺是流式處理讓集合操作變得...
    咻咻咻i閱讀 1,270評論 0 0
  • 1.流的基本概念 1.1 什么是流? 流是Java8引入的全新概念,它用來處理集合中的數(shù)據(jù),暫且可以把它理解為一種...
    升空的焰火閱讀 1,587評論 0 1

友情鏈接更多精彩內(nèi)容