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);
        }
    

      

      

     

     

  • 相关阅读:
    托付和事件的使用
    在使用supervisord 管理tomcat时遇到的小问题
    无法安装vmware tools的解决方PLEASE WAIT! VMware Tools is currently being installed on your system. Dependin
    (转)Openlayers 2.X加载高德地图
    (转)openlayers实现在线编辑
    (转) Arcgis for js加载百度地图
    (转)Arcgis for js加载天地图
    (转) 基于Arcgis for Js的web GIS数据在线采集简介
    (转) Arcgis for js之WKT和GEOMETRY的相互转换
    (转)Arcgis for Js之Graphiclayer扩展详解
  • 原文地址:https://www.cnblogs.com/mabaoying/p/12903073.html
Copyright © 2011-2022 走看看