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);
    }
原文地址:https://www.cnblogs.com/menbo/p/13696637.html