一说明

经过前一篇的StreamAPI学习,基本的流操作我相信大家都熟练于心了,那么今天是要详细解析一下收集器(collect)这么API
前提要区分,collect(StreamAPI)与collection(集合),collectors(StreamAPI静态工厂是一种归约操作)是个不同的东西

二 Collect

初始化信息

    public List<Car> InitCar(){
        ArrayList<Car> carList = new ArrayList<>();
        Car car1 = new Car("100", "black", "中国", 20);
        Car car2 = new Car("101", "gray", "中国", 30);
        Car car3 = new Car("102", "yello", "中国", 50);
        Car car4 = new Car("103", "silvery", "英国", 20);
        Car car5 = new Car("104", "red", "英国", 30);
        carList.add(car1);
        carList.add(car2);
        carList.add(car3);
        carList.add(car4);
        carList.add(car5);
        return carList;
    }

1数量

    @Test
    public void countTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求数量
        Long count = cars.stream().collect(Collectors.counting());
        System.out.println(count);//5
    }

2 最大值

    @Test
    public void maxTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求车价格最大值的车
        Comparator<Car> carComparator = Comparator.comparingDouble(Car::getPrice);
        Optional<Car> maxOptional = cars.stream().collect(Collectors.maxBy(carComparator));
        // Car(code=102, color=yello, factory=中国, price=50.0)
        System.out.println(maxOptional.get());
    }

3 最小值

    @Test
    public void minTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求车价格最小值的车
        Comparator<Car> carComparator = Comparator.comparingDouble(Car::getPrice);
        Optional<Car> maxOptional = cars.stream().collect(Collectors.minBy(carComparator));
        // Car(code=100, color=black, factory=中国, price=20.0)
        System.out.println(maxOptional.get());
    }

4求和

   @Test
    public void sumTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求所有车价格的总和
        Double collect = cars.stream().collect(Collectors.summingDouble(Car::getPrice));
        System.out.println(collect);//150.0
    }

5求均值

    @Test
    public void avgTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求所有车价格的均值
        Double collect = cars.stream().collect(Collectors.averagingDouble(Car::getPrice));
        System.out.println(collect);//30.0
    }

6字符串连接

   @Test
    public void joinTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求所有车颜色字符串的拼接
        String collect = cars.stream().map(Car::getColor).collect(Collectors.joining(","));
        System.out.println(collect);//black,gray,yello,silvery,red
    }

7 归约

    @Test
    public void reduceTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求所有车价格的总和
        Double collect = cars.stream()
                .collect(Collectors.reducing(0.0, Car::getPrice, (number, number2) -> number + number2));
        System.out.println(collect);//150.0
    }

8 分组

根据车的制造地分组。分为 中国和英国2组

    @Test
    public void groupingByTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 根据车的制造地分组
        Map<String, List<Car>> collect = cars.stream()
                .collect(Collectors.groupingBy(Car::getFactory));
        //{中国=[Car(code=100, color=black, factory=中国, price=20.0),
        // Car(code=101, color=gray, factory=中国, price=30.0),
        // Car(code=102, color=yello, factory=中国, price=50.0)], 
        // 英国=[Car(code=103, color=silvery, factory=英国, price=20.0),
        // Car(code=104, color=red, factory=英国, price=30.0)]}
        System.out.println(collect);
    }

9 多级分组

    @Test
    public void moreGroupingByTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 根据车的制造地分组,再根据车的价格分组
        Map<String, Map<Double, List<Car>>> collect = cars.stream()
                .collect(Collectors.groupingBy(Car::getFactory, Collectors.groupingBy(Car::getPrice)));
        //{中国={20.0=[Car(code=100, color=black, factory=中国, price=20.0)], 
        // 50.0=[Car(code=102, color=yello, factory=中国, price=50.0)], 
        // 30.0=[Car(code=101, color=gray, factory=中国, price=30.0)]}, 
        // 英国={20.0=[Car(code=103, color=silvery, factory=英国, price=20.0)], 
        // 30.0=[Car(code=104, color=red, factory=英国, price=30.0)]}}

        System.out.println(collect);
    }

10 分区

分区是分组里面的一种,只根据true,false进行分组。

    @Test
    public void groupingByAndCountTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 根据车的价格是否大于30分区
        Map<Boolean, List<Car>> collect = cars.stream()
                .collect(Collectors.partitioningBy(o -> o.getPrice() > 30));
        //{false=[Car(code=100, color=black, factory=中国, price=20.0),
        // Car(code=101, color=gray, factory=中国, price=30.0), 
        // Car(code=103, color=silvery, factory=英国, price=20.0), 
        // Car(code=104, color=red, factory=英国, price=30.0)], 
        // true=[Car(code=102, color=yello, factory=中国, price=50.0)]}
        System.out.println(collect);
    }

11 收集为List

    @Test
    public void toListTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 
        List<String> collect = cars.stream()
                .map(Car::getColor)
                .collect(Collectors.toList());
        // [black, gray, yello, silvery, red]
        System.out.println(collect);
    }

12 收集为set

    @Test
    public void toSetTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 
        Set<Double> collect = cars.stream()
                .map(Car::getPrice)
                .collect(Collectors.toSet());
        // [20.0, 50.0, 30.0]
        System.out.println(collect);
    }

13 提取key-val转为map

    @Test
    public void toMapTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 提取新元素key,val转为map
        Map<String, Double> collect = cars.stream()
                .collect(Collectors.toMap(Car::getColor, Car::getPrice));
        // {red=30.0, gray=30.0, black=20.0, yello=50.0, silvery=20.0}
        System.out.println(collect);
    }

14 提取元素归约收集

    public void mapperTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 提取 元素转为List
        List<String> collect = cars.stream()
                .collect(Collectors.mapping(Car::getColor, Collectors.toList()));
        // [black, gray, yello, silvery, red]
        System.out.println(collect);
    }

三 特别说明

之前的求和,平均值,最大值等还有一种求法,主要是 double ,int long类型。以下示例是double型。

    @Test
    public void summarizingTest(){
        List<Car> cars = carFunFactory.InitCar();
        // 求所有车价格的总和
        DoubleSummaryStatistics collect = cars.stream().collect(Collectors.summarizingDouble(Car::getPrice));
        System.out.println(collect.getSum());//150.0
        System.out.println(collect.getAverage());//30.0
        System.out.println(collect.getMax());//50.0
        System.out.println(collect.getMin());//20.0
        System.out.println(collect.getCount());//5
    }

四致谢

这次搜集器讲完,打算后面再讲解一下并行流,后面就会进入时间操作,有兴趣爱学习的朋友可以关注我公众号,支持一下,谢谢。
java8-StreamAPI之collection归约操作-风君雪科技博客