zoukankan      html  css  js  c++  java
  • java8新特性学习三(Stream API)

     java8中有两大最为重要的改变。一个是Lambda表达式,另一个是Stream API。

    Stream 中文称为 “流”,通过将集合转换为这么一种叫做 “流” 的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作。Stream API提供了一种高效且易于使用的处理数据的方式。

    先说下Stream的优势:Collection是一种静态的内存数据结构,面向内存存储在内存中,而Stream是有关计算的,面向CPU通过CPU实现计算的。它是java对集合操作的优化,相较于迭代器,使用Stream的速度非常快,并且它支持并行方式处理集合中的数据,默认情况能充分利用cpu的资源。同时支持函数式编程,代码非常简洁。

    注意:

    stream自己不会存储元素;

    Stream不会改变源对象。相反,它会返回一个持有结果的新Stream;

    Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

    Stream的操作三步骤

    1.创建stream

    Stream的创建需要一个数据源(通常是一个容器或者数组):

    @Test
        public void test1(){
            //方法一、通过集合创建stream
            List<String> list= Arrays.asList("aa","dd","cc","bb","mm","zz");
            //返回一个顺序流
            Stream<String> stream1 = list.stream();
            //返回一个并行流
            Stream<String> stringStream1 = list.parallelStream();
    
            //方法二、通过数组创建stream
            int[] array={1,2,3,4,5};
            IntStream stream2 = Arrays.stream(array);
    
            //方法三、通过stream类中的静态方法of创建
            Stream<String> stream3 = Stream.of("I", "love", "you", "too");
    
            //方法四、创建无限流
            //迭代,遍历前十个偶数
            Stream<Integer> stream4 = Stream.iterate(0, t -> t + 2);
            stream4.limit(10).forEach(System.out::println);
            //生成
            Stream.generate(Math::random).limit(10).forEach(System.out::println);
        }

    2.中间操作

    多个中间操作可以连成一条流水线,除非流水线触发终止操作,不然中间操作不会执行任何的处理,属于延迟加载。

    中间操作就是对容器的处理过程,包括:排序(sorted...),筛选(filter,limit,distinct...),映射(map,flatMap...)等

     2.1 筛选与切片

    filter(Predicate<? super T> predicate):从流中过滤某些元素

    limit(long maxSize):截断流

    skip(n):跳过前n个元素,与limit配合使用实现分页操作

    distinct:去重,使用了hashCode和equals方法来获取不同的元素,因此我们的类必须实现hashCode和equals方法。

        @Test
        public void test2(){
            User user1=new User("1003","张三",25,"成都");
            User user2=new User("1004","李四",22,"绵阳");
            User user3=new User("1002","王五",24,"南充");
            User user4=new User("1005","赵六",23,"广元");
            User user5=new User("1001","张三",21,"成都");
            User user6=new User("1003","张三",25,"南充");
            User user7=new User("1004","李四",22,"绵阳");
            User user8=new User("1003","张三",25,"成都");
            List<User> list=Arrays.asList(user1,user2,user3,user4,user5,user6,user7,user8);
    
            //filter过滤
            list.stream().filter(u->u.getAge()>=24).forEach(System.out::println);
            System.out.println("******************");
    
            //limit截断
            list.stream().filter(u->"张三".equals(u.getName())).limit(2).forEach(System.out::println);
            System.out.println("******************");
    
            //skip
            list.stream().skip(2).limit(5).forEach(System.out::println);
            System.out.println("******************");
    
            //skip,User类需实现hashCode与equals方法
            list.stream().filter(u->"张三".equals(u.getName())).distinct().forEach(System.out::println);
        }
    

    2.2 映射

    map(function f):接收一个函数作为参数,将元素转换为其他形式或提取信息,该函数会被应用到每一个元素上,并将其映射为一个新的元素。
    flatMap(function f):接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
     @Test
        public void test3(){
            //map(function f)
            List<String> list= Arrays.asList("aa","dd","cc","bb","mm","zz");
            list.stream().map(str->str.toUpperCase()).forEach(System.out::println);
            System.out.println("***********");
    
            User user1=new User("1003","张三",25,"成都");
            User user2=new User("1004","李四",22,"绵阳");
            User user3=new User("1002","王五",24,"南充");
            List<User> list2=Arrays.asList(user1,user2,user3);
            list2.stream().map(User::getName).forEach(System.out::println);
    
            //flushMap(function f)
            System.out.println("*********");
            list.stream().flatMap(StreamTest::filterCharactor).forEach(System.out::println);
        }
    
        public static Stream<Character> filterCharactor(String str){
            List<Character> list=new ArrayList<>();
            for(Character ch:str.toCharArray()){
                list.add(ch);
            }
            return list.stream();
        }

    2.3 排序

    sorted():自然排序,其中的元素必须实现Comparable接口;

    sorted(Comparator com):定制排序,我们可以使用lambda来创建一个Comparator实例,可以按照升序或者降序来排序元素。

    @Test
        public void test4(){
            //sorted():自然排序:Comparable
            List<String> list= Arrays.asList("aa","dd","cc","bb","mm","zz");
            list.stream().sorted().forEach(System.out::println);
    
            System.out.println("**************");
            //sorted(Comparator com) --定制排序
            User user1=new User("1001","张三",25,"南充");
            User user2=new User("1002","李四",22,"绵阳");
            User user3=new User("1003","王五",25,"成都");
            User user4=new User("1004","赵六",21,"乐山");
            User user5=new User("1005","田七",22,"南充");
            List<User> list2=Arrays.asList(user1,user2,user3,user4,user5);
            
            list2.stream().sorted((u1,u2)->{
                if(u1.getAge().equals(u2.getAge())){
                    return u1.getName().compareTo(u2.getName());
                }else{
                    return -u1.getAge().compareTo(u2.getAge());
                }
            }).forEach(System.out::println);
        }

    3.终止操作

    一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用。

    3.1查找与匹配

    allMatch 检查是否匹配所有元素
    anyMatch 检查是否至少匹配一个元素
    noneMatch 检查是否没有匹配所有元素
    findFirst 返回第一个元素
    findAny 返回当前流中的任意元素
    count 返回流中元素的总个数
    max 返回流中最大值
    min 返回流中最小值
    @Test
        public void test5(){
            User user1=new User("1001","张三",26,"南充");
            User user2=new User("1002","李四",22,"绵阳");
            User user3=new User("1003","王五",25,"成都");
            User user4=new User("1004","赵六",21,"乐山");
            User user5=new User("1005","田七",22,"南充");
            List<User> list1=Arrays.asList(user1,user2,user3,user4,user5);
            //allMatch
            boolean b1 = list1.stream().allMatch(u -> u.getAge() == 22);
            System.out.println("allMatch==="+b1);
            //anyMatch
            boolean b2 = list1.stream().anyMatch(u -> u.getAge() == 22);
            System.out.println("anyMatch==="+b2);
            //noneMatch
            boolean b3 = list1.stream().noneMatch(u -> u.getAge() == 22);
            System.out.println("noneMatch==="+b3);
            //findFirst
            Optional<User> first = list1.stream().sorted((u1, u2) ->
                                    Integer.compare(u1.getAge(), u2.getAge())).findFirst();
            System.out.println(first.get());
            //findAny
            System.out.println("-------------------");
            Optional<User> any = list1.stream().findAny();
            System.out.println(any.get());
            //count
            long count = list1.stream().count();
            System.out.println("count==="+count);
            //max
            Optional<User> max = list1.stream().max((u1, u2) -> Integer.compare(u1.getAge(), u2.getAge()));
            System.out.println(max.get());
            //min
            Optional<Integer> min = list1.stream().map(User::getAge).min(Integer::compare);
            System.out.println(min.get());
        }

     3.2 归约

    reduce(T identity,BinaryOperator):可以将流中元素反复结合起来,得到一个值。返回T
    reduce(BinaryOperator):返回Optional<T>
      @Test
        public void test6(){
            //reduce(T t,BinaryOperator b)
            List<Integer> list1=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
            Integer sum = list1.stream().reduce(0, (x, y) -> x + y);
            System.out.println("sum="+sum);
    
            //reduce(BinaryOperator b)
            User user1=new User("1001","张三",26,"南充");
            User user2=new User("1002","李四",22,"绵阳");
            User user3=new User("1003","王五",25,"成都");
            User user4=new User("1004","赵六",21,"乐山");
            User user5=new User("1005","田七",22,"南充");
            List<User> list2= Arrays.asList(user1,user2,user3,user4,user5);
            Optional<Integer> sumAge = list2.stream().map(u -> u.getAge()).reduce(Integer::sum);
            System.out.println("sumAge="+sumAge.get());
        }
    

      3.3 收集

    collect(Collector c):将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法。

    Collector接口中方法的实现决定了如何对流执行收集操作(如收集到List、set、map)。但是Collectors实用类提供了很多静态方法,可以方便地创建常见收集器实例。

     @Test
        public void test7(){
            User user1=new User("1001","张三",26,"南充");
            User user2=new User("1002","李四",22,"成都");
            User user3=new User("1003","王五",25,"成都");
            User user4=new User("1004","赵六",21,"乐山");
            User user5=new User("1005","张三",22,"南充");
            List<User> list1= Arrays.asList(user1,user2,user3,user4,user5);
    
            //收集list
            List<String> list = list1.stream().map(u -> u.getName()).collect(Collectors.toList());
            list.forEach(System.out::println);
    
            System.out.println("---------------------");
            //收集set
            Set<String> set = list1.stream().map(u -> u.getName()).collect(Collectors.toSet());
            set.forEach(System.out::println);
    
            System.out.println("---------------------");
            //收集平均值
            Double avg = list1.stream().collect(Collectors.averagingInt(User::getAge));
            System.out.println("avg="+avg);
    
            System.out.println("----------------");
            //收集sum
            int sum = list1.stream().collect(Collectors.summingInt(User::getAge));
            System.out.println("sum="+sum);
    
            System.out.println("----------------");
            //收集max
            Optional<User> maxUser = list1.stream().collect(Collectors.maxBy((u1, u2) -> Integer.compare(u1.getAge(), u2.getAge())));
            System.out.println(maxUser);
    
            System.out.println("----------------");
            //收集min
            Optional<Integer> min = list1.stream().map(User::getAge).collect(Collectors.minBy(Integer::compare));
            System.out.println(min.get());
    
            System.out.println("----------------");
            //分组
            Map<String, List<User>> groupUser = list1.stream().collect(Collectors.groupingBy(User::getAddress));
            System.out.println(groupUser);
    
            System.out.println("----------------");
            //分区
            Map<Boolean, List<User>> partMap = list1.stream().collect(Collectors.partitioningBy(u -> u.getAge() > 24));
            System.out.println(partMap);
    
            System.out.println("----------------");
            //连接字符串
            String str = list1.stream().map(User::getName).collect(Collectors.joining(","));
            System.out.println(str);
        }
    

      

      

     

     

  • 相关阅读:
    百度地图设置div样式宽高为百分比不显示地图
    C#添加修改控件css样式
    斐波那契查找原理详解与实现
    JavaWeb 如何在web.xml中配置多个servlet
    eclipse中添加tomcat ServerName 无法输入
    java 面试题
    JSON 转 对象
    Eclipse 导入Maven 项目报错
    Mybatis 中 update 语句 动态 语句
    oracle 将当前系统时间戳插入timestamp字段
  • 原文地址:https://www.cnblogs.com/mabaoying/p/12903073.html
Copyright © 2011-2022 走看看