博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java8新特性Stream详解
阅读量:4035 次
发布时间:2019-05-24

本文共 6737 字,大约阅读时间需要 22 分钟。

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类,以后我们每次都是操作这个类

public class Student {
private Integer id; private String name; private Integer age; private Double score; public Student() {
} public Student(Integer id, String name, Integer age, Double score) {
this.id = id; this.name = name; this.age = age; this.score = score; } //getter和setter方法 //toString方法}

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

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

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

2、创建一个Stream

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

@Testpublic void test1(){
List
studentList = StudentData.getStudents(); //第一种:返回一个顺序流 Stream
stream = studentList.stream(); //第二种:返回一个并行流 Stream
stream2 = studentList.parallelStream();}

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

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

方式三:通过Stream.of

@Test    public void test3(){
Stream
integerStream = Stream.of(1, 2, 3, 5, 6, 7, 8); Stream
stringStream = Stream.of("1", "2", "3", "4", "5"); Stream
studentStream = Stream.of( new Student(1, "刘备", 18, 90.4), new Student(2, "张飞", 19, 87.4), new Student(3, "关羽", 21, 67.4)); }

方式四:创建一个无限流

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

3、使用Stream操作数据

操作1:筛选和切片

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

操作2:映射

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

操作3:排序

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

4、终止Stream

操作1:匹配和查找

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

操作2:归约

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

操作3:收集

public void test3(){
List
studentList = StudentData.getStudents(); //返回一个list List
listStream = studentList.stream() .filter(e -> e.getAge() > 18) .collect(Collectors.toList()); //返回一个Set Set
setStream = studentList.stream() .filter(e -> e.getAge() > 18) .collect(Collectors.toSet()); //返回其他的类型 }

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

> 喜欢的可以关注我的微信公众号:java的架构师技术栈,获取更多文章和教程资源

转载地址:http://psbdi.baihongyu.com/

你可能感兴趣的文章
S3C2440 USB 设备控制器(转)
查看>>
Linux usb 设备驱动 (1)
查看>>
解决跨网场景下,CAS重定向无法登录的问题(无需修改现有代码)
查看>>
java反编译命令
查看>>
activemq依赖包获取
查看>>
概念区别
查看>>
关于静态块、静态属性、构造块、构造方法的执行顺序
查看>>
final 的作用
查看>>
在Idea中使用Eclipse编译器
查看>>
idea讲web项目部署到tomcat,热部署
查看>>
优化IDEA启动速度,快了好多。后面有什么优化点,会继续往里面添加
查看>>
JMeter 保持sessionId
查看>>
IDEA Properties中文unicode转码问题
查看>>
Idea下安装Lombok插件
查看>>
zookeeper
查看>>
Idea导入的工程看不到src等代码
查看>>
技术栈
查看>>
Jenkins中shell-script执行报错sh: line 2: npm: command not found
查看>>
8.X版本的node打包时,gulp命令报错 require.extensions.hasownproperty
查看>>
Jenkins 启动命令
查看>>