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

  

  

 

 

猜你喜欢

转载自www.cnblogs.com/mabaoying/p/12903073.html