java8-StreamAPI之collection归约操作
一说明
经过前一篇的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
}
四致谢
这次搜集器讲完,打算后面再讲解一下并行流,后面就会进入时间操作,有兴趣爱学习的朋友可以关注我公众号,支持一下,谢谢。