Java8新特性之Stream流

Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,课执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来进行执行操作。简而言之,Stream API提供了一种高效且易于使用的处理数据的方式

注意:

  1. Stream自己不会存储元素
  2. Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream
  3. Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

创建Stream

Java8中的Collection接口被扩展,提供了两个获取流的方法:

  • default Stream<E> stream():返回一个顺序流
  • default Stream<E> parallelStream():返回一个并行流
    //创建Stream
    @Test
    public void test1(){
        //1.可以通过Collection系列集合提供的stream()-串行流或parallelStream()-并行流
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();

        //2.通过Arrays中的静态方法stream()获取数组流
        Employee[] emp = new Employee[10];
        Stream<Employee> stream1 = Arrays.stream(emp);

        //3.通过Stream类中的静态方法of()
        Stream<String> stream2 = Stream.of("aa","bb","cc");

        //4.创建无限流
        //迭代
        Stream<Integer> stream3 = Stream.iterate(0,x->x+2);
        stream3.limit(10).forEach(System.out::println);


    }

Stream的中间操作

 

 

 

     @Test
    public void test(){
        Integer[] num = new Integer[]{1,2,3,4,5};
        Arrays.stream(num)
                .map(x->x*x)
                .forEach(System.out::println);
    }
    /*
        筛选与切片
        filter-接收Lambda,从流中排除某些元素
        limit-截断流,使其元素不超过给定数量,只要查到了给定数量的元素,就不会往下执行了
        skip-跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流。与        limit(n)互补
        distinct-筛选,通过流所生成的元素的hashCode()和equals()去除重复元素
     */

    List<Employee> employees = Arrays.asList(
            new Employee("张三",18,9999.99),
            new Employee("李四",30,5000),
            new Employee("王五",35,1111),
            new Employee("赵六",42,2222),
            new Employee("田七",19,9900),
            new Employee("田七",19,9900),
            new Employee("田七",19,9900)
    );

    //中间操作
    //内部迭代:迭代操作由Stream API完成
    @Test
    public void test1(){

        //中间操作    不会执行任何处理
        Stream<Employee> stream = employees.stream()
                 .filter(e->{
                     System.out.println("StreamAPI的中间操作");
                     return e.getAge()>35;
                 });
        //终止操作    一次性执行全部内容,即“惰性求值”
        stream.forEach(System.out::println);
    }

    @Test
    public void test2(){
        employees.stream()
                .filter(employee -> {
                    System.out.println("短路");
                    return employee.getSalary()>5000;
                })
                .limit(2)
                .forEach(System.out::println);
    }

    @Test
    public void test3(){
        employees.stream()
                .filter(employee -> {
                    System.out.println("短路");
                    return employee.getSalary()>5000;
                })
                .limit(2)
                .forEach(System.out::println);
    }

    @Test
    public void test4(){
        employees.stream()
                .skip(2)
                .filter(employee -> employee.getSalary()>5000)
                .distinct()
                .forEach(System.out::println);
    }

    /*
        映射
        map-接收Lambda,将元素转换为其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每一个元素上,
        并将其映射成一个新的元素
        flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
     */

    @Test
    public void test5(){
        List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
        list.stream()
                .map(s -> s.toUpperCase())
                .forEach(System.out::println);

        System.out.println("------------------");

        employees.stream()
                .map(employee -> employee.getName())
                .forEach(System.out::println);

        System.out.println("--------------------");

//        Stream<Stream<Character>> stream = list.stream()
//                .map(s -> filterCharacter(s));
//        stream.forEach(sm->sm.forEach(System.out::println));//{{a,a,a},{b,b,b}}

        System.out.println("--------------------");
        Stream<Character> stream=list.stream()
                .flatMap(s -> filterCharacter(s));//{a,a,a,b,b,b}

        stream.forEach(System.out::println);
    }

    public Stream<Character> filterCharacter(String str){
        List<Character> list =new ArrayList<>();
        for (Character ch:str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }

    /*
        排序
            sort()——自然排序(Comparable)
            sort(Comparator com)——定制排序
     */

    @Test
    public void test6(){
        employees.stream()
                .sorted((e1,e2)->{
                    if(e1.getAge()==e2.getAge()){
                        return e1.getName().compareTo(e2.getName());
                    }else {
                        return -e1.getAge().compareTo(e2.getAge());
                    }
                }).forEach(System.out::println);
    }

 Stream流的终止操作

 

 

    /*
        查找与匹配
        allMatch——检查是否匹配所有元素
        anyMatch——检查是否至少匹配一个元素
        noneMatch——检查是否没有匹配所有元素
        findFirst——返回第一个元素
        findAny——返回当前流中的任意元素
        count——返回六中元素的总个数
        max——返回流中最大值
        min——返回流中最小值
     */
    List<Employee> employees = Arrays.asList(
            new Employee("张三",18,9999.99d, Employee.Status.FREE),
            new Employee("李四",30,5000d,Employee.Status.BUSY),
            new Employee("王五",35,1111d, Employee.Status.VOATION),
            new Employee("赵六",42,2222d, Employee.Status.FREE),
            new Employee("田七",19,9900d, Employee.Status.BUSY)
    );
    @Test
    public void test1(){
        boolean bln = employees.stream()
                .allMatch(employee -> employee.getStatus().equals(Employee.Status.BUSY));
        System.out.println(bln);

        boolean bln2 = employees.stream()
                                .anyMatch(employee ->employee.getStatus().equals(Employee.Status.BUSY));
        System.out.println(bln2);

        boolean bln3 = employees.stream()
                .noneMatch(employee ->employee.getStatus().equals(Employee.Status.BUSY));
        System.out.println(bln3);

        Optional<Employee> first = employees.stream()
                .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();
        System.out.println(first.get());

        Optional<Employee> any = employees.stream()
                .filter(employee -> employee.getStatus().equals(Employee.Status.FREE))
                .findAny();
        System.out.println(any);
    }

    @Test
    public void test2(){
        long count = employees.stream()
                .count();
        System.out.println(count);

        Optional<Employee> max = employees.stream()
                .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(max.get());

        Optional<Double> min = employees.stream()
                .map(employee -> employee.getSalary())
                .min((e1, e2) -> Double.compare(e1, e2));
        System.out.println(min.get());
    }

    /*
            规约
            reduce(T identity,BinaryOperator)/reduce(BinaryOperator)——可以将流中元素反复结合起来,得到一个值
     */
    @Test
    public void test3(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer reduce = list.stream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(reduce);

        System.out.println("--------------------");
        Double reduce1 = employees.stream()
                .map(employee -> employee.getSalary())
                .reduce(0d, (x, y) -> x + y);
        Optional<Double> reduce2 = employees.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(reduce1);
        System.out.println(reduce2.get());
    }

 

 

 

 

    /*
        收集:
        collect——将流转换为其他形式,接受一个Collector接口的实现,用于给Stream中元素做汇总的方法
     */
    @Test
    public void test4(){
        List<String> collect = employees.stream()
                .map(employee -> employee.getName())
                .collect(Collectors.toList());
        collect.forEach(System.out::println);

        System.out.println("--------------------");
        Set<String> collect1 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());
        collect1.forEach(System.out::println);

        System.out.println("-------------------");

        HashSet<String> collect2 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));
        collect2.forEach(System.out::println);

        System.out.println("-------------------");

        Map<String, String> collect3 = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toMap(x -> x, y -> y));
        for (String key:collect3.keySet()){
            System.out.println(key+"   "+collect3.get(key));
        }

        Optional<Double> collect4 = employees.stream()
                .map(Employee::getSalary)
                .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1, e2)));
        System.out.println(collect4.get());

    }

    @Test
    public void test5(){
        //总数
        Long collect = employees.stream()
                .collect(Collectors.counting());
        System.out.println(collect);

        System.out.println("---------------");

        //平均值
        Double collect1 = employees.stream()
                .map(employee -> employee.getSalary())
                .collect(Collectors.averagingDouble(x->x));
        Double collect2 = employees.stream()
                .collect(Collectors.averagingDouble(employees -> employees.getSalary()));
        System.out.println("平均值:"+collect1+"  "+collect2);
        System.out.println("--------------------");

        //总和
        Double collect3 = employees.stream()
                .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println("总和"+collect3);
        System.out.println("--------------------");


        //最大值
        Optional<Employee> max = employees.stream()
                .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(max.get());
        System.out.println("------------------");
        //最小值
        Optional<Employee> min = employees.stream()
                .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(min.get());
        System.out.println("------------------");




    }

    //分组
    @Test
    public void test6(){
        Map<Employee.Status, List<Employee>> collect = employees.stream()
                .collect(Collectors.groupingBy(employee -> employee.getStatus()));
        System.out.println(collect);
    }

    //多级分组
    @Test
    public void test7(){
        Map<Employee.Status,Map<String,List<Employee>>> map = employees.stream()
                .collect(Collectors.groupingBy(employee -> ((Employee)employee).getStatus(),Collectors.groupingBy(employee -> {
                    if(((Employee)employee).getAge()<=35){
                        return "青年";
                    }else if(((Employee)employee).getAge()<=50){
                        return "中年";
                    }else {
                        return "老年";
                    }
                })));

        System.out.println(map);
    }

    //分区   满足条件的一个区,不满足条件的一个区
    @Test
    public void test8(){
        Map<Boolean, List<Employee>> collect = employees.stream()
                .collect(Collectors.partitioningBy(employee -> employee.getSalary() > 8000));

        System.out.println(collect);
    }

    @Test
    public void test9(){
        DoubleSummaryStatistics collect = employees.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(collect.getMax());
        System.out.println(collect.getAverage());
        System.out.println(collect.getCount());
    }

    @Test
    public void test10(){
        String collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",","==","----"));
        System.out.println(collect);
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值