欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java型特性——Stream API(Stream流)

程序员文章站 2022-05-28 11:36:43
...

Java8新特性之Stream API

Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。Stream 是
Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作,在新版的JPA中,也已经加入了Stream。如:

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();

Stream<User> readAllByFirstnameNotNull();

@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

Stream的操作步骤

Stream有如下三个操作步骤:

一,创建Stream

从一个数据源,如集合、数组中获取流。

二,中间操作

一个操作的中间链,对数据源的数据进行操作。

三,终止操作

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

要注意的是,对流的操作完成后需要进行关闭操作(或者用JAVA7的try-with-resources)。

四,Stream和parallelStream的区别

创建Stream


    /**
     * 1.通过Collection对象的Stream()和ParalleStream() 并行的,效率高
     */
    @Test
    public void test01(){
        List<String> wordsList = GetListData.wordsList;
        Stream<String> stream = wordsList.stream();
        stream.forEach(System.out::println);
		//通过方法引用对其进行简化
        GetListData.wordsList.stream().forEach(System.out::println);
    }
 /**
     * 2.通过Arrays工具类的stream方法
     */
    @Test
    public void test02(){
        String [] strArray = new String[] {"a", "b", "c"};
        Arrays.stream(strArray).forEach(System.out::println);
    }

Stream API本身自带的方法:

 /**
     * 3.通过Stream的一些方法of、iterate、generate
     */
    @Test
    public void test03(){
        Stream<Integer> stream = Stream.of(10, 20, 30, 40, 50);
        stream.forEach(System.out::println);

        Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);
        iterate.limit(10).forEach(System.out::println);

        Stream<Integer> generate = Stream.generate(() -> new Random().nextInt(100));
        generate.limit(5).forEach(System.out::println);
    }

不同的数据类型,可以创建不同类型的Stream:

/**
     * 通过IntStream、DoubleStream、LongStream....
     */
    @Test
    public void test04(){
        IntStream.of(10, 20, 30, 40).forEach(System.out::println);
    }

中间操作:Stream的聚合操作

常用的中间操作有五种:filter, limit ,skip, distinct, sort ,map

filter :接收Lambda,从流中排除某些操作;

//判断年龄大于20岁的同学
//通常会在springcloud中的zuul网关会出现
        List<Student> collect = students.stream().filter(student -> student.getAge() >= 20).collect(Collectors.toList());
        collect.forEach(System.out::println);

limit :截断流,使其元素不超过给定对象

//limit  等同于SQL语句中的limit
 students.stream().limit(2).forEach(System.out::println);

skip:跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补

//skip 跳过前两条
students.stream().skip(2).forEach(System.out::println);

distinct :筛选,通过流所生成元素的hashCode()和equals()去除重复元素。

//distinct 去重  依据equals hascode
students.stream().distinct().forEach(System.out::println);

sort :对数据进行排序

//sort  排序
//按照学生的年龄进行排序
students.stream().sorted((s1,s2)->Integer.compare(s1.getAge(),s2.getAge()))
                .forEach(System.out::println);

map:能够获取流中的一部分

//map 能够获取流中的一部分  比如只拿到学生中的姓名
List<Integer> collect = students.stream().map(student -> student.getAge()).collect(Collectors.toList());
        collect.forEach(System.out::println);

聚合中间函数

聚合中间函数 max min count reduce collect

		//SpringData-jpa  通过id查询会返回Optional的对象
		//为了防止空指针
		//获取最大
        Optional<Student> max = students.stream().max((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
        System.out.println(max.get().getAge());
		//获取最小
        Optional<Student> min = students.stream().min((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
        System.out.println(min.get().getAge());
		
		//总和
        System.out.println(students.stream().count());

        //reduce 统计年龄的总和
        Optional<Integer> reduce = students.stream().map(student -> student.getAge()).reduce((x, y) -> x + y);
        System.out.println(reduce.get());

        //collect  返回一个新的流
        List<Integer> collect = students.stream().map(student -> student.getAge()).collect(Collectors.toList());
        collect.stream().forEach(System.out::println);

Stream和parallelStream的区别

parallelStream是多线程操作
Stream是单线程操作

//创建较大数据,容易看出两者区别
 List<String> list = new ArrayList<>();
        for (int i=0;i<10000000;i++){
            list.add(UUID.randomUUID().toString());
        }
        //获取操作开始时的时间戳
        long start = System.currentTimeMillis();
        //单线程操作
        list.stream().sorted().count();
        //多线程操作
        list.parallelStream().sorted().count();
        //获取操作结束时的时间戳
        long end = System.currentTimeMillis();
        //获取这一段代码执行的时间是多长
        System.out.println(end-start);

		//最后结果为
		stream的操作时间为:6864
        parallelStream的操作时间为:2565

每天一个装逼小技巧,毕竟我们是专业的
java型特性——Stream API(Stream流)

相关标签: jdk8 新特性