java8中有两个非常有名的改进,一个是Lambda表达式,一个是Stream。如果我们了解过函数式编程的话,都知道Stream真正把函数式编程的风格引入到了java中。这篇文章由简入繁逐步介绍Stream。

一、Stream是什么

从名字来看,Stream就是一个流,他的主要作用就是对集合数据进行查找过滤等操作。有点类似于SQL的数据库操作。一句话来解释就是一种高效且易用的数据处理方式。大数据领域也有一个Steam实时流计算框架,不过和这个可不一样。别搞混了。

举个例子吧,比如说有一个集合Student数据,我们要删选出学生名字为“张三”的学生,或者是找出所有年龄大于18岁的所有学生。此时我们就可以直接使用Stream来筛选。当然了这只是给出了其中一个例子。Stream还有很多其他的功能。

Stream和Collection的区别就是:Collection只是负责存储数据,不对数据做其他处理,主要是和内存打交道。但是Stream主要是负责计算数据的,主要是和CPU打交道。现在明白了吧。

二、Stream语法讲解

Stream执行流程很简单,主要有三个,首先创建一个Stream,然后使用Stream操作数据,最后终止Stream。有点类似于Stream的生命周期。下面我们根据其流程来一个一个讲解。

1、前提准备

首先我们创建一个Student类,以后我们每次都是操作这个类

 1public class Student {
2    private Integer id;
3    private String name;
4    private Integer age;
5    private Double score;
6    public Student() {
7    }
8    public Student(Integer id, String name, Integer age, Double score) {
9        this.id = id;
10        this.name = name;
11        this.age = age;
12        this.score = score;
13    }
14    //getter和setter方法
15    //toString方法
16}

然后下面我们再创建一个StudentData类,用于获取其数据

 1public class StudentData {
2    public  static List<Student> getStudents(){
3        List<Student> list = new ArrayList<>();
4        list.add(new Student(1,"刘备",18,90.4));
5        list.add(new Student(2,"张飞",19,87.4));
6        list.add(new Student(3,"关羽",21,67.4));
7        list.add(new Student(4,"赵云",15,89.4));
8        list.add(new Student(5,"马超",16,91.4));
9        list.add(new Student(6,"曹操",19,83.4));
10        list.add(new Student(7,"荀彧",24,78.4));
11        list.add(new Student(8,"孙权",26,79.4));
12        list.add(new Student(9,"鲁肃",21,93.4));
13        return list;
14    }
15}

我们只需要把方法变成static类型的就可以了。

2、创建一个Stream

方式一:通过一个集合创建Stream

1@Test
2public void test1(){
3    List<Student> studentList = StudentData.getStudents();
4    //第一种:返回一个顺序流
5    Stream<Student> stream = studentList.stream();
6    //第二种:返回一个并行流
7    Stream<Student> stream2 = studentList.parallelStream();
8}

方式二:通过一个数组创建Stream

 1    @Test
2    public void test2(){
3        //获取一个整形Stream
4        int[] arr = new int[]{1,2,34,4,65,7,87,};
5        IntStream intStream = Arrays.stream(arr);
6        //获取一个Student对象Stream
7        Student[] students = StudentData.getArrStudents();
8        Stream<Student> stream = Arrays.stream(students);
9
10    }

方式三:通过Stream.of

 1    @Test
2    public void test3(){
3        Stream<Integer> integerStream = Stream.of(1235678);
4        Stream<String> stringStream = Stream.of("1""2""3""4""5");
5        Stream<Student> studentStream = Stream.of(
6                new Student(1"刘备"1890.4),
7                new Student(2"张飞"1987.4),
8                new Student(3"关羽"2167.4));
9
10    }

方式四:创建一个无限流

1    @Test
2    public void test4(){
3        //每隔5个数取一个,从0开始,此时就会无限循环
4        Stream.iterate(0,t->t+5).forEach(System.out::println);
5        //每隔5个数取一个,从0开始,只取前5个数
6        Stream.iterate(0,t->t+5).limit(5).forEach(System.out::println);
7        //取出一个随机数
8        Stream.generate(Math::random).limit(5).forEach(System.out::println);
9    }

3、使用Stream操作数据

操作1:筛选和切片

 1    @Test
2    public void test1(){
3        List<Student> list  = StudentData.getStudents();
4        //(1)过滤:过滤出所有年龄大于20岁的同学
5        list.stream().filter(item->item.getAge()>20).forEach(System.out::println);
6        //(2)截断流:筛选出前3条数据
7        list.stream().limit(3).forEach(System.out::println);
8        //(3)跳过元素:跳过前5个元素
9        list.stream().skip(5).forEach(System.out::println);
10        //(4)过滤重复数据:
11        list.stream().distinct().forEach(System.out::println);
12    }

操作2:映射

 1    @Test
2    public  void test2(){
3        //(1)map操作
4        List<String> list  = Arrays.asList("java","python","go");
5        Stream<String> stream = list.stream();
6        //此时每一个小写字母都有一个大写的映射
7        stream.map(str -> str.toUpperCase()).forEach(System.out::println);
8        //筛选出所有的年龄,再过滤出所有大于20的年龄有哪些
9        List<Student> studentList  = StudentData.getStudents();
10        Stream<Student> stream1 = studentList.stream();
11        Stream<Integer> ageStream = stream1.map(Student::getAge);
12        ageStream.filter(age->age>20).forEach(System.out::println);
13        //(2)floatMap:将流中的每一个值换成另外一个流
14    }

操作3:排序

 1    public  void test3(){
2        //(1)自然排序
3        List<Integer> list  = Arrays.asList(4,3,7,9,12,8,10,23,2);
4        Stream<Integer> stream = list.stream();
5        stream.sorted().forEach(System.out::println);
6        //(2)对象排序:对象类可以先实现comparable接口,或者是直接指定
7        //第一种:先实现compable接口
8        List<Student> studentList  = StudentData.getStudents();
9        studentList.stream().sorted().forEach(System.out::println);
10        //第二种:直接指定comparable
11        List<Student> studentList1  = StudentData.getStudents();
12        studentList1.stream()
13                .sorted((e1,e2)-> Integer.compare(e1.getAge(),e2.getAge()))
14                .forEach(System.out::println);
15    }

4、终止Stream

操作1:匹配和查找

 1    public void test1(){
2        List<Student> list  = StudentData.getStudents();
3        //(1)判断所有的学生年龄是否都大于20岁
4        boolean allMatch = list.stream().allMatch(item -> item.getAge() > 20);
5        //(2)判断是否存在学生的年龄大于20岁
6        boolean anyMatch = list.stream().anyMatch(item -> item.getAge() > 20);
7        //(3)判断是否存在学生叫曹操
8        boolean noneMatch = list.stream().noneMatch(item -> item.getName().equals("曹操"));
9        //(4)查找第一个学生
10        Optional<Student> first = list.stream().findFirst();
11        //(5)查找所有的学生数量
12        long count = list.stream().count();
13        long count1 = list.stream().filter(item -> item.getScore() > 90.0).count();
14        //(6)查找当前流中的元素
15        Optional<Student> any = list.stream().findAny();
16        //(7)查找学生最高的分数:Student实现了comparable接口的话,可直接比较
17        Stream<Double> doubleStream = list.stream().map(item -> item.getScore());
18        doubleStream.max(Double::compare);
19        //(8)查找学生最低的分数
20    }

操作2:归约

1    public void test2(){
2        //(1)计算数的总和
3        List<Integer> list = Arrays.asList(1,2,3,4,5);
4        list.stream().reduce(0,Integer::sum);
5        //(3)计算学生总分
6        List<Student> studentList = StudentData.getStudents();
7        Stream<Double> doubleStream = studentList.stream().map(Student::getScore);
8        doubleStream.reduce(Double::sum);
9    }

操作3:收集

 1    public void test3(){
2        List<Student> studentList = StudentData.getStudents();
3        //返回一个list
4        List<Student> listStream = studentList.stream()
5                .filter(e -> e.getAge() > 18)
6                .collect(Collectors.toList());
7        //返回一个Set
8        Set<Student> setStream = studentList.stream()
9                .filter(e -> e.getAge() > 18)
10                .collect(Collectors.toSet());
11        //返回其他的类型
12    }

stream基本的语法就是这样,你会发现Stream就像是一个工具一样,可以帮我们分析处理数据,极其的好用,但是目前还不知道其效率如何。根据网上一位大佬的内存时间分析,其实在数据量比较庞大的时候,Stream可以为我们节省大量的时间,数据量小的时候并不明显。


更多相关文章

  1. 整理了一套操作系统常见的面试题,不管你是面试大厂还是小厂都足够
  2. mysql从入门到优化(3)事务的基本操作
  3. mysql从入门到优化(1)基本操作上
  4. mysql从入门到优化(4)视图的基本操作
  5. mysql从入门到优化(2)数据的增删改查操作总结
  6. 都想学大数据开发?年轻人耗子尾汁吧~
  7. 社会化海量数据采集爬虫框架搭建
  8. 数据结构之:二分搜索树
  9. 【荐读】基于文本数据的消费者洞察

随机推荐

  1. android uiautomator 截取图片
  2. android调用隐藏的网络信息设置菜单实现
  3. Android开发----自动化测试
  4. [Android 动画]简要分析一下Animator 与
  5. Android应用的自动升级、更新模块的实现
  6. Android 以webview的方式集成Dcloud h5+S
  7. Android开机启动shell脚本(Android 8.0测
  8. Google 发布 Android 版 Chrome 浏览器,只
  9. 一个简单的demo学习Android远程Service(AI
  10. Android USB通信-实现lsusb