Java8中提供的收集器

Java8中提供的收集器

  • 作用:Collector(收集器会对元素引用一个转换函数,并且将结果累计在一个数据结构中,如toList,从而产生一个最终输出)

Java中的预定义收集器(预定义收集器定义在Collectors中,由Java自身实现我们可以直接使用)

  • 主要作用如下:
    将流元素归约和汇总为一个值
    元素分组
    元素分区

具体使用

预先定义一些类用来做示例

    public class Menu {

        private String name;
        private double weight;
    
        public Menu(String name, double weight) {
            this.name = name;
            this.weight = weight;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getWeight() {
            return weight;
        }
    
        public void setWeight(double weight) {
            this.weight = weight;
        }
    
        @Override
        public String toString() {
            return "Menu{" +
                    "name='" + name + '\'' +
                    ", weight=" + weight +
                    '}';
        }
    }
   import Java8.chapter3_stream.operate.Menu;
   import com.google.common.collect.Lists;
   import static java.util.stream.Collectors.*;
   public class App {

        public static List factory() {
            Menu meatMenu = new Menu("meat", 8.88);
            List list = Lists.newArrayList();
            list.add(new Menu("fish", 1.98));
            list.add(new Menu("apple", 0.88));
            list.add(new Menu("beaf", 2.18));
            list.add(meatMenu);
            list.add(meatMenu);
            list.add(new Menu("chop", 0.08));
            return list;
        }
    
        public static void main(String[] args) {
            List list = factory();
        }
    }

1 归约和汇总

1.1 counting() 计算数量总和的收集器
    //计算数量
    Long total = list.stream().map(Menu::getWeight).collect(counting());
    //等同写法
    long total2 = list.stream().map(Menu::getWeight).count();
    System.out.println("===t1===" + total + ",===t2===" + total2);
    
    结果:===t1===6,===t2===6
1.2 maxBy&minBy 查找流中的最大值和最小值
     //查找流中的最大值
     Optional max = list.stream().map(Menu::getWeight).collect(maxBy(Double::compare));
     //等同写法
     Optional max2 = list.stream().map(Menu::getWeight).reduce(Double::max);
     //这是reduce独有的,maxBy不存在初始值
     Double max3 = list.stream().map(Menu::getWeight).reduce(0D, Double::max);

     //查找流中的最小值
     Optional min = list.stream().map(Menu::getWeight).collect(minBy(Double::compare));
     //等同写法
     Optional min2 = list.stream().map(Menu::getWeight).reduce(Double::min);
    //这是reduce独有的,minBy不存在初始值
     Double min3 = list.stream().map(Menu::getWeight).reduce(1D, Double::min);

     System.out.println("===max==="+max+",===max2==="+max2+",===max3==="+max3);
     System.out.println("===min==="+min+",===min2==="+min2+",===min3==="+min3);
     
     结果:
    ===max===Optional[8.88],===max2===Optional[8.88],===max3===8.88
    ===min===Optional[0.08],===min2===Optional[0.08],===min3===0.08  
1.3 汇总(Collectors提供了summingInt、summingDouble、summingLong专门处理对应的三种类型,并且提供了summarizingInt、summarizingDouble、summarizingLong来汇总所有操作)
     //汇总  这是处理double另外两个同理
     //求和
     Double doubleSum = list.stream().collect(summingDouble(Menu::getWeight));
     //求平均数
     Double averageWeight = list.stream().collect(averagingDouble(Menu::getWeight));
     System.out.println("===doubleSum===" + doubleSum + ",===averageWeight===" + averageWeight);
     //将汇总操作放在一个收集器进行
     DoubleSummaryStatistics doubleSummaryStatistics = list.stream().collect(summarizingDouble(Menu::getWeight));
     System.out.println(doubleSummaryStatistics.toString());
     
     结果:
     ===doubleSum===22.88,===averageWeight===3.813333333333333
     DoubleSummaryStatistics{count=6, sum=22.880000, min=0.080000, average=3.813333, max=8.880000}
1.4 连接字符串(Collectors提供了joining方法来进行字符串的连接,并且可以重载连接的字符)
     //连接字符串
     String printStr = list.stream().map(Menu::getName).collect(joining(","));
     System.out.println("打印结果:"+printStr);
   
     结果:
     打印结果:fish,apple,beaf,meat,meat,chop
1.5 广义的规约汇总(上面这些例子是它的特殊情况) reducing()
     //reducing
     double sum = list.stream().collect(reducing(0d, Menu::getWeight, Double::sum));
     System.out.println("===sum===" + sum);
     //相同效果
     Double sum1 = list.stream().mapToDouble(Menu::getWeight).sum();
     System.out.println("===sum1===" + sum1);  
     
     结果:
     ===sum===22.880000000000003
     ===sum1===22.88

2 分组

2.1 多级分组
    //按name分类
    Map> listMap = list.stream().collect(groupingBy(Menu::getName));
    System.out.println(listMap);

    //按weight分类
    Map> collect = list.stream().collect(groupingBy(
            menu -> {
                if (menu.getWeight() > 0.9) {
                    return CaloricLevel.FAT;
                } else {
                    return CaloricLevel.DIET;
                }
            }));

    System.out.println(collect);


    //多级分组
    Map>> collect1 = list.stream().collect(groupingBy(Menu::getName, groupingBy(menu -> {
        if (menu.getWeight() > 0.9) {
            return CaloricLevel.FAT;
        } else {
            return CaloricLevel.DIET;
        }
    })));

        System.out.println(collect1);
2.2 按子组收集数据
    //按子组收集数据
    Map collect2 = list.stream().collect(groupingBy(Menu::getName, counting()));
    Map collect3 = list.stream().collect(groupingBy(Menu::getName, collectingAndThen(maxBy(Comparator.comparingDouble(Menu::getWeight)), Optional::get)));

    Map> collect4 = list.stream().collect(groupingBy(Menu::getName, mapping(menu -> {
        if (menu.getWeight() > 0.9) {
            return CaloricLevel.FAT;
        } else {
            return CaloricLevel.DIET;
        }
    }, toSet())));
    System.out.println(collect2);
    System.out.println(collect3);
    System.out.println(collect4);
2.3 分区(是分组的特殊情况,key分为true和false两种情况)
    Map> collect5 = list.stream().collect(partitioningBy(m -> m.getWeight() > 0.8));
    System.out.println(collect5);

你可能感兴趣的:(基础,Java8)