跟领导技术层面意见不合时,别犟,领导要考虑如何赚钱,你考虑如何做好,有时候错的是对的,对的反而是错的,但跟同事,必须一战到底,教他如何做一名合格的程序员。
——大龙不聋
《求职之路 | 2024年Java从入门到干活:第18章JDK8-JDK21新特性(一)——Lambda表达式》
接着上一章节,我们继续学习Java8的新特性。
目录
5、Stream API
5.1 介绍
Stream API把真正的函数式编程引入到Java中。毫不夸张的说,他是目前为止对Java类库最好的补充,它极大提升Java程序员的生产力,写出高效、简洁的代码,让程序员的思绪在指尖跳舞,牛逼的不要不要滴。
Stream API是处理集合的关键抽象概念,对集合可以执行复杂的操作,如查找、过滤、映射等等,使用起来就像使用SQL操作数据库一样操作集合。Stream API提供一种高效且易于使用的处理数据的方式。
5.2 存在的意义
我们在项目开发中,许多项目(比如web项目)数据层用Oracle、MySql等关系型数据库,这些关系型数据库通过Sql即可实现增删改查。但是现在许多项目用MongDB、NoSQL、Redis等非关系型数据库,对这些数据的处理,往往需要在Java层面进行操作了。
说的这么多,究竟啥意思?我画图解释一下哈。
一个web项目,数据源是关系型数据库,基于Sql可以完成对数据的重要操作,如下图:
一个非关系型数据库项目,我们可以在内存中基于Stream API对数据进行操作,如下图:
5.3 什么是Stream
Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列,它可以实现对数据源的复杂操作,例如查找、过滤、排序和映射等。
Stream VS Collection集合的区别:
①、Collection是一种静态的内存数据结构,存储在内存中,它的本质是数据
②、Stream是通过CPU来进行运算的,它的本质是计算
5.4 Stream的操作三个步骤
①、创建Stream
一个数据源(集合,数组),获取一个流。
②、中间操作
一个中间操作链,对数据源的数据进行处理,但在终结操作前,并不会真正执行。如筛选与切片、映射、排序。
③、终止操作
一个终止操作,执行中间操作链,最终产生结果并结束Stream。如匹配与查找、归约、收集
5.5 创建Stream的方式
5.5.1 方式一:通过集合创建
Java 8 中Collection接口中扩展两个默认方法(Java 8新特性,接口中可以扩展静态方法和默认方法):
- default Stream<E> stream() : 返回一个顺序流
- default Stream<E> parallelStream() : 返回一个并行流
public class StreamAPITest {
// 方式一:通过集合创建
// Collection | default Stream<E> stream():返回一个顺序流
// Collection | default Stream<E> parallelStream():返回一个并行流
@Test
public void test1() {
List<Employee> list = new ArrayList<>();
list.add(new Employee("张三", 35, 6899.0));
list.add(new Employee("张龙", 25, 5769.0));
list.add(new Employee("赵武", 26, 4568.0));
list.add(new Employee("马汉", 38, 7568.0));
// 创建一个顺序流
Stream<Employee> stream1 = list.stream();
stream1.forEach(System.out :: println);
System.out.println("====================我是分割线====================");
// 创建一个并行流
Stream<Employee> stream2 = list.parallelStream();
stream2.forEach(System.out :: println);
}
}
class Employee {
private String name;
private int age;
private double salary;
public Employee() {
System.out.println("Employee().....");
}
public Employee(String name) {
this.name = name;
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" + "name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}';
}
}
5.5.2 方式二:通过数组创建
Java8中Arrays静态方法stream() 可以获取数组流:
- public static IntStream stream(int[] array)
- public static LongStream stream(long[] array)
- public static DoubleStream stream(double[] array)
- static<T> Stream<T> stream(T[] array)
// 方式二:通过数组创建
// Arrays | static <T> Stream<T> stream重载方法:返回一个流
@Test
public void test2() {
// Arrays 有多个stream重载方法,可传入基本类型,也可传入类类型
int[] arr1 = new int[]{1, 2, 3, 4, 5};
IntStream stream1 = Arrays.stream(arr1);
double[] arr2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};
DoubleStream stream2 = Arrays.stream(arr2);
long[] arr3 = new long[]{1, 2, 3, 4, 5};
LongStream stream3 = Arrays.stream(arr3);
Integer[] arr4 = new Integer[]{1, 2, 3, 4, 5};
Stream<Integer> stream = Arrays.stream(arr4);
// ...
}
5.5.3 方式三:通过Stream的of()创建
可以调用Stream的静态方法of(),显示创建一个流,它的参数是可变长参数:
- public static<T> Stream<T> of(T ... values):返回一个流
// 方式三:通过Stream的o