zoukankan      html  css  js  c++  java
  • java8新特性(二)StreamApi

    Stream的作用

    stream是java8中处理集合的关键抽象信息,它可以指定希望对集合进行的操作,可以执行查找、过滤和映射数据等操作。

    使用StreamApi对集合数据进行操作,就类似于使用使用sql对数据库操作。简而言之,StreamApi提供了高效且易于使用的数据处理方式。

    什么是流?

    流指的是用于操作数据源所生成的元素序列。

    需要注意的是:

    (1)stream不会自己存储元素;

    (2)不会改变源对象,会返回一个新的stream

    (3)stream是延迟执行的,意味着它们会等到需要结果的时候才会执行。

     Stream操作的三个步骤:

    (1)创建Stream

    一个数据源(集合、数组)获取一个流;

    (2)中间操作

    一个中间操作链,对数据源的数据进行处理;

    (3)终止操作

    一个终止操作,执行中间操作链,产生结果。

    案例

    流的获取方式

       @Test
        public void test01(){
            // 可以通过Collection集合提供stream()或parallelStearam()
            List<String > list = new ArrayList<>();
            Stream<String> stream = list.stream();
            //通过Arrays的静态方法stream()获取数组流
            Employee[] employee = new Employee[10];
            Stream<Employee> stream1 = Arrays.stream(employee);
            //通过stream类中的静态方法of()
            Stream<String > stream2 = Stream.of("aa","bb","cc");
    
            //创建无限流
            Stream<Integer> stream3 = Stream.iterate(0,(x)->x+2);
            stream3.limit(10).forEach(System.out::println);
            System.out.println("-------------------------------------");
            Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
        }

    中间操作与终止操作

        @Test
        public void test02(){
    
            List<Employee> employees = Arrays.asList(new Employee("张三",23),
                    new Employee("李四",24),
                    new Employee("王五",25),
                    new Employee("王五",25));
            //中间操作:不会执行任何操作
            Stream<Employee> stream = employees.stream().filter((e)->{
                System.out.println("Stream Api中间操作");
                return e.getAge()>24;
            });
            //终止操作:一次执行全部操作,
            stream.forEach(System.out::println);
            System.out.println("---------------------------------------");
            employees.stream().filter((e)->e.getAge()>22).skip(1).forEach(System.out::println);
            System.out.println("-------------");
            //使用distinct方法要重写equals和hashcode方法
            employees.stream().filter((e)->e.getAge()>22).distinct().forEach(System.out::println);
    
        }

    映射map方法和flatMap方法

        @Test
        public void test03(){
            List<String> strings = Arrays.asList("aaa","bbb","ccc");
            strings.stream().map((str)->str.toUpperCase()).forEach(System.out::println); //接收lambda操作,该函数将操作应用到每个元素上
            System.out.println("----------------------------------");
            employees.stream().map(Employee::getAge).forEach(System.out::println);
            System.out.println("----------------------------------");
            Stream<Stream<Character>> streamStream = strings.stream().map(StreamMain::filterChareacter);//map方法返回的是stream流
            streamStream.forEach((sm)->{
                sm.forEach(System.out::print); //需要嵌套for循环
            });
            System.out.println("----------------------------------");
            Stream<Character> characterStream = strings.stream().flatMap(StreamMain::filterChareacter);//flatMap返回的是元素
            characterStream.forEach(System.out::println);//不需要嵌套for循环
    
            //map和flatMap作用的对比类似于 add和addAll方法
            // Map是相当于把一个个流加入到当前流中,
            //FlatMap是相当于把一个个元素加入到当前流中。
            Collection<Object > aList = new ArrayList();
            Collection<Object > bList = new ArrayList();
            bList.add("13");
            bList.add("14");
            aList.add("12");
            aList.add(bList);
            System.out.println(aList);
        }
    
        //对字符串进行切分
        public static Stream<Character> filterChareacter(String str){
            List<Character> list = new ArrayList<>();
            for(Character ch :str.toCharArray()){
                list.add(ch);
            }
            return list.stream();
        }

    sorted方法

       List<Employee> employees = Arrays.asList(new Employee("张三",23),
                new Employee("李四",24),
                new Employee("王五",25),
                new Employee("王五",25));    
    
    @Test
        public void test04(){
            List<String > strings = Arrays.asList("aaa","ccc","bbb","ddd");
            strings.stream().sorted().forEach(System.out::println);
            //按年龄排序  如果年龄相同则按姓名排序
            employees.stream().sorted((e1,e2)->{
                if(e1.getAge()==(e2.getAge())){
                    return e1.getUserName().compareTo(e2.getUserName());
                }else {
                    return e1.getAge().compareTo(e2.getAge());
                }
            }).forEach(System.out::println);
        }

    allmatch方法

    @Test
        public void test05(){
           boolean flag = employees.stream().allMatch((e)->e.getAge().equals(25)); //检查是否匹配所有元素
            System.out.println(flag);
    
            boolean b2 = employees.stream().anyMatch((e)->e.getAge().equals(25));
            System.out.println(b2);
    
            boolean b3 = employees.stream().noneMatch((e)->e.getAge().equals(25));//检查所有元素是否都不匹配
            System.out.println(b3);
    
            Optional<Employee> first = employees.stream().sorted((e1, e2) ->
                    -Integer.compare(e1.getAge(), e2.getAge())
            ).findFirst();
            System.out.println(first);
    
            Optional<Employee> any = employees.parallelStream().filter((e) -> e.getAge().equals(24)).findAny();
            System.out.println(any);;
        }

    count方法

        @Test
        public void test06(){
            Optional<Integer> min = employees.stream().map(Employee::getAge).min(Integer::compare);
            System.out.println(min);
    
            Optional<Employee> max = employees.stream().max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
            System.out.println(max);
    
            long count = employees.stream().count();
            System.out.println(count);
        }

    reduce 规约

        //reduce 规约
        //可以将流中的元素反复结合起来,得到一个值
        @Test
        public void test07(){
            List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
            Integer sum = nums.stream().reduce(0, (x, y) -> x + y);
            System.out.println(sum);
    
            Optional<Integer> sumInt = employees.stream().map(Employee::getAge)
                    .reduce(Integer::sum);
            System.out.println(sumInt.get());
        }

    collect方法

       //collect可以将流转化为其他形式
        @Test
        public void test08(){
            List<String> collect = employees.stream().map(Employee::getUserName)
                    .collect(Collectors.toList());
            System.out.println(collect);
            System.out.println("----------------------");
            Set<String> collectSet = employees.stream()
                    .map(Employee::getUserName)
                    .collect(Collectors.toSet());
            collectSet.forEach(System.out::println);
            System.out.println("---------------------------");
            HashSet<String> collect1 = employees.stream().map(Employee::getUserName)
                    .collect(Collectors.toCollection(HashSet::new));
            collect1.forEach(System.out::println);
        }
    
        @Test
        public void test09(){
            //总数
            Long collect = employees.stream()
                    .collect(Collectors.counting());
            System.out.println(collect);
            //平均数
            Double avg = employees.stream()
                    .collect(Collectors.averagingInt(Employee::getAge));
            System.out.println(avg);
            //总和
            Integer sum = employees.stream()
                    .collect(Collectors.summingInt(Employee::getAge));
            System.out.println(sum);
        }

    maxBy、minBy方法

        @Test
        public void test10(){
            Optional<Employee> collect = employees.stream()
                    .collect(Collectors.maxBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
            System.out.println(collect.get());
    
            Optional<Integer> collect1 = employees.stream().map(Employee::getAge)
                    .collect(Collectors.minBy(Integer::compare));
            System.out.println(collect1.get());
        }

    分组

    @Test
        public void teset01(){
            //按照某个属性分组
            Map<Integer, List<Employee>> collect = employees.stream()
                    .collect(Collectors.groupingBy(Employee::getAge));
            System.out.println(collect);
            System.out.println("----------------------------------");
            //多级分组
            Map<Integer, Map<String, List<Employee>>> collect1 = employees.stream()
                    .collect(Collectors.groupingBy(Employee::getAge, Collectors.groupingBy((e) -> {
                        if (((Employee) e).getSalary() > 24000) {
                            return "有钱人";
                        } else {
                            return "没钱人";
                        }
                    })));
            System.out.println(collect1);
        }

    分区

        //分区
        @Test
        public void test02(){
            Map<Boolean, List<Employee>> collect = employees.stream()
                    .collect(Collectors.partitioningBy((e) -> e.getSalary() > 5000));
            System.out.println(collect);
        }
  • 相关阅读:
    x64 平台开发 Mapxtreme 编译错误
    hdu 4305 Lightning
    Ural 1627 Join(生成树计数)
    poj 2104 Kth Number(可持久化线段树)
    ural 1651 Shortest Subchain
    hdu 4351 Digital root
    hdu 3221 Bruteforce Algorithm
    poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
    hdu 4031 Attack(BIT)
    LightOJ 1277 Looking for a Subsequence
  • 原文地址:https://www.cnblogs.com/menbo/p/13696637.html
Copyright © 2011-2022 走看看