Java8新特性-Stream API 之Collector(三)
2018-08-15 00:40
489 查看
Collector与Collectors之间的关系
作为collect方法的参数,Collector是一个接口,它是一个可变的汇聚操作,将输入元素累计到一个可变的结果容器中;它会在所有元素都处理完毕后,将累积的结果转换为一个最终的表示(这是一个可选操作);
Collectors本身提供了关于Collector的常见汇聚实现,Collectors的内部类CollectorImpl实现了Collector接口,Collectors本身实际上是一个工厂。
Collectors提供哪些方法
工厂方法名 | 返回类型 | 作用 |
---|---|---|
toList | List<T> | List集合 |
toSet | Set<T> | Set<T>,去重 |
maxBy | Option<T> | Optional<T> |
groupingBy | Map<key,List> | 元素分组 |
summingInt | Integer | 所有元素某个属性求和 |
averagingInt | Integer | 所有元素某个属性的平均值 |
summarizingInt | IntSummaryStatistics | 一次获取多个值, count, sum, min, max, average |
joining | String | 将所有的元素的某个属性拼接成字符串 |
reducing | 累加的类型 | 累加计算 |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果应用转换函数 |
partitioningBy | Map<Boolean,List<T>> | 根据对流中每个项目应用谓词的结果来对项目进行分区 |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果应用转换函数 |
public class CollectorsDemo { public static void main(String[] args) { List<Dish> menu = Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), new Dish("beef", false, 700, Dish.Type.MEAT), new Dish("chicken", false, 400, Dish.Type.MEAT), new Dish("french fries", true, 530, Dish.Type.OTHER), new Dish("rice", true, 350, Dish.Type.OTHER), new Dish("season fruit", true, 120, Dish.Type.OTHER), new Dish("pizza", true, 550, Dish.Type.OTHER), new Dish("prawns", false, 300, Dish.Type.FISH), new Dish("salmon", false, 450, Dish.Type.FISH)); //maxby test 筛选出最大的元素 Comparator<Dish> dishCaloriesComparator = comparingInt(Dish::getCalories); menu.stream().collect(maxBy(dishCaloriesComparator)) .ifPresent(a -> System.out.println("max calories --->" + a.getCalories())); //groupingby test 将元素的某个属性提取出来进行分组 Map<Dish.Type, List<Dish>> map = menu.stream().collect(groupingBy(Dish::getType)); for (Map.Entry<Dish.Type, List<Dish>> entry : map.entrySet()) { System.out.println(entry.getKey() + "---" + entry.getValue().size()); } //summingInt test 计算所有元素的和 int totalCalories = menu.stream().collect(summingInt(Dish::getCalories)); //averagingInt test 计算所有元素的平均值 double averageCalories = menu.stream().collect(averagingInt(Dish::getCalories)); //summarizingInt test 一次获取多个值, count, sum, min, max, average IntSummaryStatistics menuStatistics = menu.stream().collect(summarizingInt(Dish::getCalories)); System.out.println(menuStatistics.toString()); //join test joining(",") 可以指定连接符,避免拼接字符串,还要对最后一个元素进行特殊处理 // 如:每个元素拼接 element+"," 最后去掉最后一个","号 String shortMenu = menu.stream().map(Dish::getName).collect(joining(",")); System.out.println("join test --->" + shortMenu); //reducing 实现 menu.stream().collect(Collectors.reducing( 0, //初始值 Dish::getCalories, //转换函数 (a, b) -> a + b)); //累计函数 menu.stream().collect(Collectors.reducing(0, Dish::getCalories, Integer::sum)); //获取热量最高的值,默认值有可能为空所以返回Optional, menu.stream().collect(Collectors.reducing( (d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2)) .ifPresent(a -> System.out.println("max calories---" + a.getCalories())); // 根据需要修改key,修改lambda表达式里面的逻辑 Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream().collect( groupingBy(dish -> { return getLevel(dish); })); //二级分组 Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloricLevel = menu.stream().collect( groupingBy(Dish::getType, groupingBy(dish -> { return getLevel(dish); }) ) ); //获取每种类型中热量最高的dish Map<Dish.Type, Optional<Dish>> mostCaloricByType = menu.stream() .collect(groupingBy(Dish::getType, maxBy(comparingInt(Dish::getCalories)))); //将optional直接转换要用collectingAndThen Map<Dish.Type, Dish> mostCaloricDish = menu.stream() .collect(groupingBy(Dish::getType, Collectors.collectingAndThen( maxBy(comparingInt(Dish::getCalories)), Optional::get))); //格式化value的方法 Map<Dish.Type, Set<CaloricLevel>> caloricLevelsByType = menu.stream().collect( groupingBy(Dish::getType, Collectors.mapping( dish -> { return getLevel(dish); }, Collectors.toSet()))); //分区partitioningBy test,传入谓词 Map<Boolean, List<Dish>> partitionedMenu = menu.stream().collect(Collectors.partitioningBy(Dish::isVegetarian)); //只返回符合条件的 List<Dish> vegetarianDishes = menu.stream().filter(Dish::isVegetarian).collect(Collectors.toList()); System.out.println(vegetarianDishes.size()); } public enum CaloricLevel {DIET, NORMAL, FAT} public static CaloricLevel getLevel(Dish dish){ if (dish.getCalories() <= 400) return CaloricLevel.DIET; else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; else return CaloricLevel.FAT; } }阅读更多
相关文章推荐
- Java 8新特性:Stream API
- Java8新特性之Stream API
- Java8新特性Stream API与Lambda表达式详解(1)
- 详解Java8特性之Stream API补充
- Java 8新特性:新语法方法引用和Lambda表达式及全新的Stream API
- Java 8新特性:Stream API
- Java 8新特性:Stream API
- Java 8新特性:新语法方法引用和Lambda表达式及全新的Stream API
- Java8新特性Stream API与Lambda表达式详解(1)
- 详解Java8特性之Stream API
- Java8新特性之Stream API
- Java 8新特性:全新的Stream API (三) 转载整理
- Java 8新特性 Stream API 编程
- 详解Java8特性之Stream API并行流
- Java8 新特性之Stream API
- java8新特性之Stream API(二)
- Java 8新特性:全新的Stream API
- Java8 Lambda表达式与Stream API (二): Stream API的使用
- jdk7 新特性-Java语言的动态性-脚本语言支持api-脚本的编译04
- Java 8 Stream API详解--转