0
点赞
收藏
分享

微信扫一扫

基础stream

凉夜lrs 2022-01-05 阅读 16
package com.ling.stream;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Package: com.ling.stream
 * @ClassName: Collection
 * @Author: Ling
 * @Date: 2021/7/21 10:14
 * @Description:
 * Iterator
 */
public class Collection {
    public static void main(String[] args) {
//        a();
//        b();
//        c();
//        d();
//        e();
//        f();
//        g();
//        h();
//        one();
//        two();
//        twoTestOne();
//        three();
//        four();
//        five();
//        fiveTwo();
//        six();
//        seven();
//        eight();
//        nine();
//        ten();
//        eleven();
//        twelve();
//        test();
    }

    private static void a(){
        List<Integer> list = new ArrayList<>();
        list.add(3);list.add(2);list.add(1);list.add(4);list.add(5);

        // 大于 2 的第一个
        list.stream().filter(a -> a > 2).findFirst().stream().map(x -> x).forEach(x -> System.out.print(x + "  "));

        System.out.println();

        // 未知
//        int num = list.stream().reduce((first, second) -> second).orElse(0);
//        System.out.println(num);

        // findFirst(list.get(list.size()-1))
        List<String> lista = Arrays.asList("node", "java", "c++", "react", "javascript");
        String result = lista.stream().reduce((first, second) -> second).orElse("no last element");
        System.out.println(result);


        // 大于2的最后一个
        List list1 = list.stream().filter(a -> a > 2).collect(Collectors.toList());
        System.out.println(list1.get(list1.size()-1));
    }

    private static void b(){

        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,23,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));

        // 根据年龄进行排序(正序)
        listPerson.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList()).forEach(System.out::println);
        System.out.println();
        // 根据年龄进行排序(倒叙)
        listPerson.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList()).forEach(System.out::println);
        System.out.println();
        // 获取最后一个人的姓名
        System.out.println(new ArrayList<>(listPerson).get(listPerson.size()-1).name);
        System.out.println();
        // 根据年龄进行排序(正序)再根据 salary 进行排序(倒叙)
        listPerson.stream().sorted(Comparator.comparing(Person::getAge).thenComparing(Person::getSalary).reversed()).forEach(System.out::println);
        System.out.println();


//                        filter:过滤流中的某些元素
        List<Integer> list = new ArrayList<>();
        list.add(3);list.add(2);list.add(1);list.add(4);list.add(5);list.add(8);list.add(42);
        list.add(17);list.add(79);list.add(78);list.add(78);list.add(124);list.add(232);list.add(12);
        // 判断大于四的
        list.stream().filter(x -> x > 4).forEach(System.out::print);
        System.out.println();
        // distinct() 去重   skip:获取n个元素   limit:获取n个元素
        list.stream().filter(x -> x > 4).distinct().skip(2).limit(2).forEach(System.out::print);
        System.out.println();

    }

    private static void c(){
        // 案例四:获取Integer集合中的最大值。
        List<Integer> list2 = Arrays.asList(1,2,6,3,7,4,2);
        // 自然排序
        Optional<Integer> max = list2.stream().max(Integer::compareTo);
        // 自定义排序
        Optional<Integer> max2 = list2.stream().max(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println("自然排序(自带方法):" + max.get());
        System.out.println("自定意排序(最大值):" + max2.get());
    }

    private static void d(){
        String[] arr1 = {"a","b","c","d"};
        String[] arr2 = {"r","a","g","j"};

        Stream<String> stream1 = Stream.of(arr1);
        Stream<String> stream2 = Stream.of(arr2);
        Stream<String> stream3 = Stream.of(" ",""," ",null);
        Stream<String> stream4 = Stream.of(arr2);

        // System.out.println(stream1 + "   " + stream2);
        // 合并,去重(distinct())
        List<String> listA = Stream.concat(stream1,stream2).collect(Collectors.toList());
        List<String> listB = Stream.concat(stream4,stream3).collect(Collectors.toList());
//        System.out.println(listA + "    " + listB);

        // limit(a) 表示输出 a 个,Stream.iterate(b,c -> c + d) 表示 以 b 开始,间隔 d 个
        // Stream.iterate(b,x -> x + d).limit(a)  以 b 开始,每次间隔 d 个,输出 a 个
        List<Integer> listC = Stream.iterate(2,x -> x + 3).limit(7).collect(Collectors.toList());
//        System.out.println(listC);

//        [0, 2, 4]
//        List<Integer> listD = Stream.iterate(0,x -> x + 2).limit(3).collect(Collectors.toList());
//        [6,8,10]
        // .skip(a) 是在运行结果上截去 a 个,之后在判断运行结果的个数符合 limit(b) 中的 b 的个数,如果符合则输出,
        // 不符合则继续进行Stream.iterate(b,c -> c + d) 进行计算,当个数符合 limit(b) 中 b 的个数,则是最后的结果
        List<Integer> listD = Stream.iterate(0,x -> x + 2).skip(3).limit(3).collect(Collectors.toList());
        System.out.println(listD);
        Stream.iterate(0,x -> x + 2).skip(3).limit(3).collect(Collectors.toList()).forEach(System.out::println);
    }

    private static void e(){
        ArrayList<Person> person = new ArrayList<>();
        person.add(new Person("甲一",3000,21,"man","aa"));
        person.add(new Person("甲二",3100,22,"woman","bb"));
        person.add(new Person("甲三",3200,23,"man","cc"));
        person.add(new Person("甲四",3300,24,"woman","dd"));
        person.add(new Person("甲五",3400,25,"man","ee"));
        // 结果: false  false  false    true  true
        person.stream().map(x -> x.age > 23).forEach(x -> System.out.print(x + "   "));
        System.out.println();
        // 结果:Person{name='甲四', salary=3300, age=24, sex='woman', area='dd'}  Person{name='甲五', salary=3400, age=25, sex='man', area='ee'}
        person.stream().filter(x -> x.age > 23).forEach(x -> System.out.print(x + "  "));


        // 求工资之和方式1:
        // 通过 .map(...) 获取 Person 对象中的 工资,然后在进行sum的求取
        Optional<Integer> sumSalary = person.stream().map(Person::getSalary).reduce(Integer::sum);

        // 以下两种  都会将 personList.stream().reduce(x,(...)...) 中的 x 和传入的参数做相加操作,只做一次
        // 求工资之和方式2:
        Integer sumSalary2 = person.stream().reduce(0, (sum, p) -> sum += p.getSalary(),
                Integer::sum);
//        Integer sumSalary2 = person.stream().reduce(0, (sum, p) -> sum += p.getSalary(),
//                (sum1, sum2) -> sum1 + sum2);
        // 求工资之和方式3:
        Integer sumSalary3 = person.stream().reduce(1000, (sum, p) -> sum += p.getSalary(), Integer::sum);

        // 以下两种都会将 reduce(x,(...)..) 中比较数 x 比较,若 x 比传入进行比较的数都大,则会输出 x 不会输出传入的参数
        // 求最高工资方式1:
        Integer maxSalary = person.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
                Integer::max);
        // 求最高工资方式2:
        Integer maxSalary2 = person.stream().reduce(1000, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
                (max1, max2) -> max1 > max2 ? max1 : max2);

        System.out.println("工资之和:" + sumSalary.get() + "," + sumSalary2 + "," + sumSalary3);
        System.out.println("最高工资:" + maxSalary + "," + maxSalary2);
    }

    public static void f(){
//        reduce:使某一特定事物在数量、程度或大小上变小或变少。
        String reduceA = Stream.of("1","2",""," ","3","4").reduce("",String::concat);
        System.out.println("1:" + reduceA);
        Optional<String> rB = Stream.of("1","2",""," ","3","4").reduce(String::concat);
        String reduceB = rB.get();
        System.out.println("2:" + reduceB);
        System.out.print("3:");
        Stream.of("1","2",""," ","3","4").reduce(String::concat).stream().forEach(System.out::println);

    }

    public static void g(){
//        reducing 是一个收集器(操作),从字面意义上可以理解为“减少操作”:输入多个元素,在一定的操作后,元素减少。
        List<Person> listPerson = new ArrayList<>();
        //                Person 类
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
//        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
//        listPerson.add(new Person("甲三",3200,23,"man","cc"));
//        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
//        listPerson.add(new Person("甲五",3400,25,"man","ee"));
        // 每个员工减去起征点后的薪资之和
        // reducing括号中的 0 则会添加到最后的结果中
        // i 是在定义 Collections.reduing() 中紧跟着的 数据,而 j 则是 要进行操作的数据
        Integer sum = listPerson.stream().collect(Collectors.reducing(500,
                Person::getSalary,(i,j) -> (i + j - 500)));
        System.out.println("员工减去起征点后的薪资之和:"+sum);
        // stream 中的 reduce 原意:减少,缩小
        // 根据指定的计算模型将Stream中的值计算得到一个最终结果
        Optional<Integer> sum2 = listPerson.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("员工薪资总和:"+sum2.get());
    }

    public static void h(){
        Stream<Integer> integerStream = Arrays.stream(new Integer[]{1, 1});

        // 求集合元素只和
            //   Arrays.stream(new Integer[]{1, 1}).reduce(x,包装类::sum)    是将 x+1+1 把最后的sum结果输出
        Integer result = integerStream.reduce(1,Integer::sum);
        System.out.println(result);

        // 求和
        integerStream = Arrays.stream(new Integer[]{1,2,3,4});
        integerStream.reduce((i, j) -> i + j).ifPresent(System.out::println);
//        integerStream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
    }



    private static void one(){
        List<Integer> list = new ArrayList<>();
        list.add(1);list.add(2);list.add(3);list.add(4);
        Optional<Integer> any = list.parallelStream().findAny();
        System.out.println(any);
        list.parallelStream().forEach(a->{
            System.out.println(a);
        });
    }

    /**
     * Stream  基础用法
     * @return
     */
    private static void two(){
        List<Integer> list = Arrays.asList(0,5,9,3,7,59,2,8,55,1);
        // 遍历出符合条件的元素

        // (大于6的第一个)  list.stream().filter(x -> x > 6).forEach(System.out::println);
        // (小于6的第一个)  list.stream().filter(x -> x < 6).forEach(System.out::println);
        System.out.print("所有小于6的:");
        list.stream().filter(x -> x < 6).forEach(System.out::print);
        System.out.println();
        // 小于6的最后一个
        System.out.print("小于6的最后一个:");
        List list1 = list.stream().filter(x -> x < 6).collect(Collectors.toList());
        System.out.print(list1.get(list1.size()-1));
//        list.stream().filter(a -> a > 6).forEach(System.out::println);

        System.out.println();

        //  匹配第一个
        //  Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
        //  Optional<Integer> first = list.stream().findFirst();  匹配 list 的第一个元素
        //  Optional<Integer> first = list.stream().filter(x -> x > 6).findFirst();  匹配 list 中大于 6 的第一个元素
        Optional<Integer> first = list.stream().filter(x -> x > 8).findFirst();
//        list.stream().filter(x -> x > 5).findFirst();
        System.out.println(first);

        // 匹配任意(适用于并行流)
        Optional<Integer> any = list.parallelStream().findAny();
        list.parallelStream().forEach(a->{
            System.out.println(a);
        });
        System.out.println(any);

        // 是否包含特定元素
        // anyMatch() 有一个小于6的则是true,否则是false
        // allMatch() 全部都是小于6的则是true,否则是false
        boolean b1 = list.stream().anyMatch(x -> x < 6);
        boolean b2 = list.stream().allMatch(x -> x < 6);
        System.out.println("匹配大于某一个值的第一个值:"+first.get());
        System.out.println("匹配任意一个值:"+any.get());
        System.out.println("是否存在小于6的值:"+b1);
        System.out.println("是否存在小于6得值:"+b2);
    }

    /**
     * 关于 Stream 基础用法的一些练习
     * @return
     */
    private static void twoTestOne(){
        // 案例一:筛选出Integer集合中大于7的元素,并打印出来
        List<Integer> list = Arrays.asList(1,8,3,6,2,9,5,7,3,4);
        list.stream().filter(x -> x > 7 ).forEach(System.out::print);
        System.out.println();

        // 案例二:筛选员工中工资高于3200的人,并形成新的集合。  形成新集合依赖collect(收集)
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));
        // 工资大于 3200 输出姓名
        List<String> stringList = listPerson.stream().filter(x -> x.getSalary() > 3200 )
                .map(Person::getName).collect(Collectors.toList());
        // 年龄小于23 的输出姓名
        List<String> listN = listPerson.stream().filter(x -> x.getAge() < 23).map(Person::getName)
                .collect(Collectors.toList());

        System.out.println("工资大于 3200 输出姓名:"+stringList);
        System.out.println("年龄小于23 的输出姓名:"+listN);

        // 获取工资最高的 --->  max
        // Comparator.comparing  进行比较排序
        Optional<Person> listS = listPerson.stream().max(Comparator.comparing(Person::getSalary));
        Optional<Person> optionalPerson = listPerson.stream().min(Comparator.comparing(Person::getAge));

        System.out.println("获取工资最高的:"+listS.get().getName()+" "+listS.get().getSalary());
        System.out.println("年龄最小的:"+optionalPerson);
        System.out.println("年龄最小的:"+optionalPerson.get().getName());

        //案例三:获取String集合中最长的元素。
        List<String> list1 = Arrays.asList("admin","re","orange","cow");
        Optional<String> optionalS = list1.stream().max(Comparator.comparing(String::length));

        System.out.println(optionalS.get());

    }

    /**
     * 聚合(max/min/count)
     * @return
     */
    private static void three(){
        // 案例四:获取Integer集合中的最大值。
        List<Integer> list2 = Arrays.asList(1,2,6,3,7,4,2);
        // 自然排序
        Optional<Integer> max = list2.stream().max(Integer::compareTo);
        // 自定义排序
        Optional<Integer> max2 = list2.stream().max(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println("自然排序(自带方法):"+max.get());
        System.out.println("自定意排序(最大值):"+max2.get());

        //案例五:计算Integer集合中大于6的元素的个数。
        List<Integer> list3 = Arrays.asList(1,8,9,7,77,76,67,78,79,0);
        // java.lang.Math.toIntExact()是java中的内置数学函数,该函数返回long参数的值
        Integer integer = Math.toIntExact(list3.stream().filter(x -> x > 6).count());
        long l = list3.stream().filter(x -> x > 6).count();
        System.out.println("集合中大于6的元素的个数(1):" + integer + "  集合中大于6的元素的个数(2):" + l);
    }

    /**
     * 映射(map/flatMap)
     *  映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为 map 和 flatMap:
     *      map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
     *      flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
     * @return
     */
    private static void four(){
        // 案例一:英文字符串数组的元素全部改为大写。整数数组每个元素+3。
        String[] str = {"abed","accuses","calcium","AONadja"};
        List<String> strList = Arrays.stream(str).map(String::toUpperCase).collect(Collectors.toList());

        List<Integer> list = Arrays.asList(1,3,7,93,26,73,2,7,8);
        List<Integer> intList = list.stream().map(x -> x + 3).collect(Collectors.toList());;
        System.out.println("数组元素变成大写:"+strList);
        System.out.println("整数数组+3:"+intList);
        System.out.println();

        // 案例二:将员工的薪资全部增加 1000。
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));
        // 不改变原来员工集合的方式
        List<Person> listPersonNew = listPerson.stream().map(person -> {
            Person personNew = new Person(person.getName(), 0,0,null,null);
            personNew.setSalary(person.getSalary()+1000);
            return personNew;
        }).collect(Collectors.toList());
        System.out.println("一次改动前:"+listPerson.get(0).getName() + " ---> " + listPerson.get(0).getSalary());
        System.out.println("一次改动后:"+listPersonNew.get(0).getName() + " ---> " + listPersonNew.get(0).getSalary());
        // 改变原来员工集合的方式
        List<Person> listPersonNewTwo = listPerson.stream().map(person -> {
            person.setSalary(person.getSalary()+1000);
            return person;
        }).collect(Collectors.toList());
        System.out.println("二次改动前:"+listPerson.get(1).getName()+" ---> "+ listPerson.get(1).getSalary());
        System.out.println("二次改动后:"+listPersonNewTwo.get(1).getName()+" ---> "+ listPersonNewTwo.get(1).getSalary());

    }

    /**
     * 归约(reduce)
     *     归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。
     * @return
     */
    private static void five(){
        //归约  案例一:求Integer集合的元素之和、乘积和最大值。
        List<Integer> list1 = Arrays.asList(1,2,3,4,5,6,7,8,9);
        // 求和方式
        Optional<Integer> sum1 = list1.stream().reduce((x,y) -> x + y);
        // 求和方式 二
        Optional<Integer> sum2 = list1.stream().reduce((Integer::sum));
        // 求和方式 三
        Integer sum3 = list1.stream().reduce(0,Integer::sum);

        //求乘积
        Optional<Integer> product = list1.stream().reduce((x,y) -> x * y);

        // 求最大值方式 一
        Optional<Integer> max1 = list1.stream().reduce((x,y) -> x > y ? x: y);
        // 求最大值方式 二
        // 将 list1 中的元素与 reduce(x,Integer::max);  中的 x 进行比较,然后谁大输出谁
        Integer max2 = list1.stream().reduce(99,Integer::max);

        System.out.println("求和方式一:"+sum1.get()+" 求和方式二:"+sum2.get()+" 求和方式三:"+sum3);
        System.out.println("乘积:"+product.get());
        System.out.println("最大值方式一:"+max1.get()+" 最大值方式二:"+max2);

    }

    /**
     * 归约
     * @return
     */
    private static void fiveTwo(){
        //归约  案例二:求所有员工的工资之和和最高工资。
        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("甲一",3000,21,"man","aa"));
        personList.add(new Person("甲二",3100,22,"woman","bb"));
        personList.add(new Person("甲三",3200,23,"man","cc"));
        personList.add(new Person("甲四",3300,24,"woman","dd"));
        personList.add(new Person("甲五",3400,25,"man","ee"));

        // 求工资之和方式1:
        // 通过 .map(...) 获取 Person 对象中的 工资,然后在进行sum的求取
        Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum);

        // 以下两种  都会将 personList.stream().reduce(x,(...)...) 中的 x 和传入的参数做相加操作,只做一次
        // 求工资之和方式2:
        Integer sumSalary2 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),
                (sum1, sum2) -> sum1 + sum2);
        // 求工资之和方式3:
        Integer sumSalary3 = personList.stream().reduce(1000, (sum, p) -> sum += p.getSalary(), Integer::sum);

        // 以下两种都会将 reduce(x,(...)..) 中比较数 x 比较,若 x 比传入进行比较的数都大,则会输出 x 不会输出传入的参数
        // 求最高工资方式1:
        Integer maxSalary = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
                Integer::max);
        // 求最高工资方式2:
        Integer maxSalary2 = personList.stream().reduce(1000, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
                (max1, max2) -> max1 > max2 ? max1 : max2);

        System.out.println("工资之和:" + sumSalary.get() + "," + sumSalary2 + "," + sumSalary3);
        System.out.println("最高工资:" + maxSalary + "," + maxSalary2);
    }

    /**
     * 收集
     * collect,收集,可以说是内容最繁多、功能最丰富的部分了。从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。
     * @return
     */
    /**
     * 归集(toList/toSet/toMap)
     * 因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。toList、toSet和toMap比较常用,另外还有toCollection、toConcurrentMap等复杂一些的用法
     * @return
     */
    public static void six(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
        List<Integer> listNew = list.stream().filter(x -> x % 2 == 0 ).collect(Collectors.toList());
        System.out.println("list "+listNew);

        Set<Integer> set1 = list.stream().collect(Collectors.toSet());
        Set<Integer> set2 = list.stream().filter(x -> x % 2 ==0 ).collect(Collectors.toSet());
        System.out.println("set1 "+set1+"  set2 "+set2);

        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));

        Map<?,Person> map = listPerson.stream().filter(p -> p.getSalary() > 3200).collect(Collectors.toMap(Person::getName, p -> p));
        System.out.println("map "+map);
    }

    /**
     * 统计(count/averaging)
     * Collectors 提供了一系列用于数据统计的静态方法:
     *      计数:count
     *      平均值:averagingInt、averagingLong、averagingDouble
     *      最值:maxBy、minBy
     *      求和:summingInt、summingLong、summingDouble
     *      统计以上所有:summarizingInt、summarizingLong、summarizingDouble
     * @return
     */
    private static void seven(){
//        案例:统计员工人数、平均工资、工资总额、最高工资。
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));

        // 求员工总数
        Long count = listPerson.stream().collect(Collectors.counting());
        // 求平均工资
        Double avg = listPerson.stream().collect(Collectors.averagingDouble(Person::getSalary));
        // 工资总额
        Double integer = listPerson.stream().collect(Collectors.summingDouble(Person::getAge));
        Double sum = listPerson.stream().collect(Collectors.summingDouble(Person::getSalary));
        // 最高工资 (compare 是 compareTo 接口的方法)
        Optional<Integer> max = listPerson.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
        // 最低工资
        Optional<Integer> min = listPerson.stream().map(Person::getSalary).collect(Collectors.minBy(Integer::compareTo));
        // 一次性统计所有信息
        Double collect = listPerson.stream().collect(Collectors.summingDouble(Person::getSalary));

        System.out.println("员工总数:"+count);
        System.out.println("平均工资:"+avg);
        System.out.println("工资总额:"+sum);
        System.out.println("最高工资:"+max.get());
        System.out.println("最低工资:"+min.get());
        System.out.println("一次性统计所有信息:"+collect);
    }

    /**
     * 分组(partitioningBy/groupingBy)
     *      分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
     *      分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
     * @return
     */
    public static void eight(){
//        案例:将员工按薪资是否高于3200分为两部分;将员工按性别和地区分组
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));

        // 按薪资是否高于3000
        Map<Boolean,List<Person>> map = listPerson.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 3000));
        // 按照性别分组
        Map<String,List<Person>> map1 = listPerson.stream().collect(Collectors.groupingBy(Person::getSex));
        // 先按照性别分组,再按地区分组
        Map<String,Map<String,List<Person>>> mapMap = listPerson.stream()
                .collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
        System.out.println("按薪资是否高于3000"+map);
        System.out.println("按照性别分组"+map1);
        System.out.println("先按照性别分组,再按地区分组"+mapMap);


    }

    /**
     * 接合(joining)
     * joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
     * @return
     */
    public static void nine(){
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));

        String names = listPerson.stream().map(p -> p.getName()).collect(Collectors.joining(","));
        System.out.println("所有员工的姓名:"+names);
        List<String> list = Arrays.asList("A","B","C");
        String string = list.stream().collect(Collectors.joining("-"));
        System.out.println("拼接后的字符串:"+string);
    }

    /**
     * 归约(reducing)
     * Collectors类提供的reducing方法,相比于stream本身的reduce方法,增加了对自定义归约的支持。
     * @return
     */
    public static void ten(){
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));
        // 每个员工减去起征点后的薪资之和
        // reducing括号中的 0 则会添加到最后的结果中
        Integer sum = listPerson.stream().collect(Collectors.reducing(0,
                Person::getSalary,(i,j) -> (i + j - 500)));
        System.out.println("员工减去起征点后的薪资之和:"+sum);
        // stream 中的reduce
        Optional<Integer> sum2 = listPerson.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("员工薪资总和:"+sum2.get());
    }

    /**
     * 排序(sorted)
     * sorted():自然排序,流中元素需实现Comparable接口
     * sorted(Comparator com):Comparator排序器自定义排序
     * 主要是通过:--> 排序的集合.stream().sorted(Comparator.comparing(排序的条件(比如姓名、工资等))).map(输出的内容(比如性别、年龄等)).collect(Collectors.toList());
     * @return
     */
    public static void eleven(){
//        案例:将员工按工资由高到低(工资一样则按年龄由大到小)排序
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person("甲一",3000,21,"man","aa"));
        listPerson.add(new Person("甲二",3100,22,"woman","bb"));
        listPerson.add(new Person("甲三",3200,23,"man","cc"));
        listPerson.add(new Person("甲四",3300,24,"woman","dd"));
        listPerson.add(new Person("甲五",3400,25,"man","ee"));

        // 按工资升序排序(自然排序)
        List<String> listP = listPerson.stream().sorted(Comparator.comparing(Person::getSalary))
                .map(Person::getName).collect(Collectors.toList());
        // 按工资倒序排序(只输出姓名)
        List<String> listI = listPerson.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
                .map(Person::getName).collect(Collectors.toList());
        // 按工资倒序排序(输出全部)
        List<Person> listAll = listPerson.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
                .collect(Collectors.toList());
        // 先按工资再按年龄升序排序
        List<String> listS = listPerson.stream().sorted(Comparator.comparing(Person::getSalary)
                .thenComparing(Person::getAge)).map(Person::getName).collect(Collectors.toList());
        // 先按工资再按年龄进行自定义排序(降序)
        List<String> listD = listPerson.stream().sorted((p1,p2) -> {
            if (p1.getSalary().equals(p2.getSalary())){
                return p2.getAge()-p1.getAge();
            } else {
                return p2.getSalary()-p1.getSalary();
            }
        }).map(Person::getName).collect(Collectors.toList());


        System.out.println("按工资升序排序(自然排序):"+listP);
        System.out.println("按工资倒序排序只输出姓名:"+listI);
        System.out.println("按工资倒序排序输出全部:"+listAll);
        System.out.println("先按工资再按年龄升序排序:"+listS);
        System.out.println("先按工资再按年龄进行自定义排序(降序):"+listD);
        List<Integer> list = listPerson.stream().sorted(Comparator.comparing(Person::getAge))
                .map(Person::getSalary).collect(Collectors.toList());
        System.out.println("通过年龄排序最后输出工资:"+list);
    }

    /**
     * 提取/组合
     * 流也可以进行合并、去重、限制、跳过等操作。
     * @return
     */
    public static void twelve(){
        String[] arr1 = {"a","b","c","d"};
        String[] arr2 = {"r","a","g","j"};
        Stream<String> stream1 = Stream.of(arr1);
        Stream<String> stream2 = Stream.of(arr2);
        // concat:合并两个流 distinct: 去重
        List<String> listC = Stream.concat(stream1,stream2).distinct().collect(Collectors.toList());
        // limit: 限制从流中获得前n个数据
        // Stream.iterate(0,x -> x + 1).limit(7).collect(Collectors.toList()); 中的 0 是代表的初始值,
        // 而 0 则赋予了 x 的值,后面的 limit(7) 代表的是 输出7个字符,因为是 x+1 所以是依次增加
        List<Integer> listI = Stream.iterate(0,x -> x + 1).limit(7).collect(Collectors.toList());
        // skip:跳过前n个数据
        // Stream.iterate(0,x -> x + 1).skip(3).limit(3).collect(Collectors.toList()); 中的 0 和 x+1 都是和之前一样
        // 在原本结果是中 输出0 1 2 3 但是 skip(3) 是截取3个,所以就是 3  但是 limit(3) 是获得3个数据,所以就会按照 x+1 的形式继续运行
        // 直到满足 limit(3) 的条件
        List<Integer> listS = Stream.iterate(0,x -> x + 2).skip(3).limit(3).collect(Collectors.toList());
        System.out.println("合并两个流,去重:"+listC);
        System.out.println("限制从流中获得前n个数据:"+listI);
        System.out.println("跳过前n个数据:"+listS);
        // 以上两个循环几次的话,个人感觉是在 limit(x) 中的 x ,x代表的输出的几个,
        // 当skip(y)后的长度不符合 limit(x)中的长度应该会自动在进行运算,使长度达到limit(x) 中 x 的长度
    }


    public static void test(){
        int[] a = new int[]{1,2,3,4,5,6};
        Integer integer = Arrays.stream(a).reduce(0,Integer::sum);
        System.out.println(integer);
    }

}
举报

相关推荐

0 条评论