Java8 Stream API学习案例2

package model;

import com.google.common.collect.Lists;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 汇总操作,分区,分组,和自定义流收集器
 *
 * @since 2020年2月23日22:19:26
 * {@link java.util.stream.Collectors}
 */
public class Java8StreamTest2 {

    public static void main(String[] args) {
//        test001();
//        test002();

//        test003();

//        test004();
//        test005();

//        test006();

//        test007();

//        test009();

        test010();
    }


    /**
     * @see java.util.stream.Collectors#groupingBy(Function)
     * @see Collectors#counting() //流的元素个数
     * @see Collectors#maxBy(Comparator) //流中最大的
     * @see Collectors#minBy(Comparator) //流中最小的
     * @see Collectors#averagingInt(ToIntFunction) //流中元素的平均值
     * @see Collectors#summingInt(ToIntFunction) //流中的元素求和汇总
     * @see Collectors#reducing(BinaryOperator) //流中的元素汇总,可以求和,可以找最大,最小,平均值
     * @see Collectors#joining() //字符串连接汇总
     */
    public static void test001() {
        List<String> list = Lists.newArrayList("xx", "zz", "yy");
        String retStr = list.stream().collect(Collectors.joining("|"));
        System.out.println(retStr);//xx|zz|yy

        List<Integer> list2 = Lists.newArrayList(1, 2, 3, 4, 5, 5, 6);
        Optional<Integer> max = list2.stream().collect(Collectors.maxBy(Integer::compareTo));
        System.out.println(max.get());//6
        Integer max2 = list2.stream().collect(Collectors.reducing(0, Integer::max));
        System.out.println(max2);//6
        //有拆箱,有性能损耗
        Integer sum = list2.stream().collect(Collectors.summingInt(Integer::intValue));
        System.out.println(sum);//26
    }

    /**
     * 分组
     */
    public static void test002() {

        List<Dish> dishes = new ArrayList<>();
        dishes.add(Dish.builder().name("apple").type(1).build());
        dishes.add(Dish.builder().name("banana").type(1).build());
        dishes.add(Dish.builder().name("orange").type(1).build());
        dishes.add(Dish.builder().name("fish").type(2).build());
        dishes.add(Dish.builder().name("vegetable").type(3).build());
        //按类型分组,每组有多少个
        Map<Integer, Long> collect = dishes.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.counting()));
        System.out.println(collect);//{1=3, 2=1, 3=1}

    }

    /**
     * 多级分组,先按类型分组,在每组按热量分组
     */
    public static void test003() {
        List<Dish> dishes = new ArrayList<>();
        dishes.add(Dish.builder().name("apple").type(1).calories(60).build());
        dishes.add(Dish.builder().name("banana").type(1).calories(100).build());
        dishes.add(Dish.builder().name("pear").type(1).calories(90).build());
        dishes.add(Dish.builder().name("orange").type(1).calories(80).build());
        dishes.add(Dish.builder().name("fish").type(2).calories(200).build());
        dishes.add(Dish.builder().name("vegetable").type(3).calories(30).build());
        //每个类型有哪些,每个类型中高热量的有哪些
        Map<Integer, Map<String, List<Dish>>> collect = dishes.stream()
                .collect(Collectors.groupingBy(Dish::getType, Collectors.groupingBy(dish -> {
                    if (dish.getCalories() > 80) return "level calories";
                    else return "high calories";
                })));

        System.out.println(collect);
        //java8遍历map entrySet 方式推荐
        collect.entrySet().stream().forEach(t -> {
            System.out.println("===" + t.getKey());
//            System.out.println(t.getValue());
            t.getValue().entrySet().stream().forEach(map2 -> {
                System.out.println(map2.getKey());
                System.out.println(map2.getValue());
            });
        });

        /**
         * ===1
         * level calories
         * [Dish(id=0, name=banana, calories=100, isVegetarian=false, type=1), Dish(id=0, name=pear, calories=90, isVegetarian=false, type=1)]
         * high calories
         * [Dish(id=0, name=apple, calories=60, isVegetarian=false, type=1), Dish(id=0, name=orange, calories=80, isVegetarian=false, type=1)]
         * ===2
         * level calories
         * [Dish(id=0, name=fish, calories=200, isVegetarian=false, type=2)]
         * ===3
         * high calories
         * [Dish(id=0, name=vegetable, calories=30, isVegetarian=false, type=3)]
         */

    }


    /**
     * 多级分组,先按类型分组,在每组取热量最大的
     */
    public static void test004() {
        List<Dish> dishes = new ArrayList<>();
        dishes.add(Dish.builder().name("apple").type(1).calories(60).build());
        dishes.add(Dish.builder().name("banana").type(1).calories(100).build());
        dishes.add(Dish.builder().name("orange").type(1).calories(80).build());
        dishes.add(Dish.builder().name("fish").type(2).calories(200).build());
        dishes.add(Dish.builder().name("vegetable").type(3).calories(30).build());
        //每个类型有哪些,每个类型中热量最大的
        Map<Integer, Optional<Dish>> collect = dishes.stream().collect(Collectors.groupingBy(Dish::getType,
                Collectors.maxBy(Comparator.comparing(Dish::getCalories))));
        collect.entrySet().stream().forEach(dish -> {
            System.out.println(dish.getKey());
            System.out.println(dish.getValue().get().getName());
        });
        /**
         * 1
         * banana
         * 2
         * fish
         * 3
         * vegetable
         */
    }

    /**
     * 把收集器的结果转化为另一种类型
     * 查找每个子组中热量最高的Dish
     * <p>
     * Map<Integer, Optional<Dish>>
     * 里面的Optional 包装去掉写法
     */
    public static void test005() {
        List<Dish> dishes = new ArrayList<>();
        dishes.add(Dish.builder().name("apple").type(1).calories(60).build());
        dishes.add(Dish.builder().name("banana").type(1).calories(100).build());
        dishes.add(Dish.builder().name("orange").type(1).calories(80).build());
        dishes.add(Dish.builder().name("fish").type(2).calories(200).build());
        dishes.add(Dish.builder().name("vegetable").type(3).calories(30).build());

        Map<Integer, Dish> collect = dishes.stream().collect(
                Collectors.groupingBy(Dish::getType, //分类函数
                        Collectors.collectingAndThen(//包装后的收集器
                                Collectors.maxBy(Comparator.comparingInt(Dish::getCalories)),//取热量最大的
                                Optional::get)

                ));

        collect.entrySet().forEach(dish -> {
            System.out.println(dish.getKey());
            System.out.println(dish.getValue());
        });
        /**
         * 1
         * Dish(id=0, name=banana, calories=100, isVegetarian=false, type=1)
         * 2
         * Dish(id=0, name=fish, calories=200, isVegetarian=false, type=2)
         * 3
         * Dish(id=0, name=vegetable, calories=30, isVegetarian=false, type=3)
         */
    }

    /**
     * 查询每种类型的食谱的能量总和
     *
     * @see Collectors#groupingBy(Function, Collector)
     * @see Collectors#summingInt(ToIntFunction)
     */
    public static void test006() {
        List<Dish> dishes = getData();
        Map<Integer, Integer> collect = dishes.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.summingInt(Dish::getCalories)));
        collect.entrySet().forEach(m -> {
            System.out.println(m.getKey());
            System.out.println(m.getValue());
        });

        /**
         * 1
         * 240
         * 2
         * 200
         * 3
         * 30
         */
    }

    private static List<Dish> getData() {
        List<Dish> dishes = new ArrayList<>();
        dishes.add(Dish.builder().name("apple").type(1).calories(60).isVegetarian(false).build());
        dishes.add(Dish.builder().name("banana").type(1).calories(100).isVegetarian(false).build());
        dishes.add(Dish.builder().name("orange").type(1).calories(80).isVegetarian(false).build());
        dishes.add(Dish.builder().name("fish").type(2).calories(200).isVegetarian(false).build());
        dishes.add(Dish.builder().name("Flat Beans").type(3).calories(30).isVegetarian(true).build());//扁豆
        return dishes;
    }

    /**
     * groupingby 联合mapping 收集器做转换
     *
     * @see Collectors#mapping(Function, Collector)
     */

    public static void test007() {
        List<Dish> dishes = getData();
        Map<Integer, Set<String>> collect = dishes.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.mapping(dish -> {
            if (dish.getCalories() > 80) return "high dish";
            else if (dish.getCalories() > 50) return "normal dish";
            else return "level dish";
        }, Collectors.toCollection(HashSet::new))));//Collectors.toCollection(HashSet::new)

        collect.entrySet().stream().forEach(map -> {
            System.out.println(map.getKey());
            map.getValue().stream().forEach(System.out::println);
        });

        /**
         * 1
         * normal dish
         * high dish
         * 2
         * high dish
         * 3
         * level dish
         */
    }

    /**
     * 分区
     * <p>分区是分组的一种特殊情况,只有true,false 两组</p>
     *
     * @see Collectors#partitioningBy(Predicate)
     */
    public static void test009(){
        List<Dish> dishes = getData();
        Map<Boolean, List<Dish>> collect = dishes.stream().collect(Collectors.partitioningBy(Dish::isVegetarian));

        collect.entrySet().stream().forEach(dish->{
            System.out.println(dish.getKey());
            dish.getValue().stream().forEach(System.out::println);
        });

        /**
         * false
         * Dish(id=0, name=apple, calories=60, isVegetarian=false, type=1)
         * Dish(id=0, name=banana, calories=100, isVegetarian=false, type=1)
         * Dish(id=0, name=orange, calories=80, isVegetarian=false, type=1)
         * Dish(id=0, name=fish, calories=200, isVegetarian=false, type=2)
         * true
         * Dish(id=0, name=Flat Beans, calories=30, isVegetarian=true, type=3)
         */
    }

    /**
     * 分区的一个重载方法
     * @see Collectors#partitioningBy(Predicate, Collector)
     *
     * //先分区后分组
     * 先按是不是蔬菜分组,之后再每组中有哪些类型分组
     */

    public static void test010(){
        List<Dish> dishes = getData();
        Map<Boolean, Map<Integer, List<Dish>>> collect = dishes.stream().collect(Collectors.partitioningBy(Dish::isVegetarian, Collectors.groupingBy(Dish::getType)));

        collect.entrySet().stream().forEach(b->{
            System.out.println(b);
            b.getValue().entrySet().stream().forEach(m->{
                System.out.println(m.getKey());
                m.getValue().stream().forEach(v-> System.out.println(v.getName()));
            });
        });

        /**
         * false={1=[Dish(id=0, name=apple, calories=60, isVegetarian=false, type=1), Dish(id=0, name=banana, calories=100, isVegetarian=false, type=1), Dish(id=0, name=orange, calories=80, isVegetarian=false, type=1)], 
         * 2=[Dish(id=0, name=fish, calories=200, isVegetarian=false, type=2)]}
         * 1
         * apple
         * banana
         * orange
         * 2
         * fish
         * true={3=[Dish(id=0, name=Flat Beans, calories=30, isVegetarian=true, type=3)]}
         * 3
         * Flat Beans
         */
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值