目录
✨这里是第七人格的博客✨小七,欢迎您的到来~✨
🍅系列专栏:无🍅
✈️本篇内容: Java Stream✈️
🍱本篇收录完整代码地址:无🍱
楔子
仅以此篇献给曾经被Stream流惊艳到的自己,和爱好学习的你。
Java Stream和集合的区别
Stream流和集合在Java中的主要区别如下:
-
数据结构:Stream流不是数据结构,而是一种处理数据的抽象概念。它不存储元素,而是通过计算操作管道传递来自源的元素。集合是一种传统的数据结构,用于存储和操作一组对象。
-
处理方式:Stream流允许以声明性方式处理数据集合,可以通过链式调用一系列的操作来处理数据。集合提供了丰富的方法来查询和操作数据,如添加、删除、修改元素等。
-
并行处理:Stream流支持并行处理,可以充分利用多核处理器的优势来提高处理速度。集合不支持并行处理。
-
延迟计算:Stream流支持延迟计算,只有在需要时才会计算结果。这样可以节省内存和计算资源。集合在创建时就分配了内存空间,无法实现延迟计算。
-
可读性:Stream流的操作更加声明式,易于阅读和理解。集合的操作相对繁琐,可读性较差。
Java Stream的组成
Java Stream 由三部分组成:Stream Source(流源)、Stream Processing(流处理)和 Stream Sink(流接收器)。
-
Stream Source(流源):Stream Source 是数据的来源,可以是集合、数组、I/O 通道等。Stream Source 提供了一种抽象的接口,使得我们可以方便地从多个数据源中获取数据。
-
Stream Processing(流处理):Stream Processing 是对 Stream Source 中的数据进行操作的过程。在 Java 8 中,Stream Processing 是通过 Stream API 来实现的,它提供了一系列的中间操作和终端操作,可以对数据进行过滤、映射、排序等操作。
-
Stream Sink(流接收器):Stream Sink 是将 Stream Processing 的结果输出到某个目的地的接口。在 Java 8 中,Stream Sink 可以是文件、数据库、网络连接等,也可以是其他数据结构,如集合或数组。通过 Stream Sink,我们可以将流处理的结果保存到磁盘、数据库或其他存储设备中。
Java Stream的操作分类
1、中间操作不会立即执行,而是返回一个新的流,这个新的流可以被进一步处理或收集到结果容器中。
2、终端操作会触发实际的计算和输出,将结果返回给调用方。
Java Stream的使用例子
首先创建基础演示类,包含演示对象Student
public class StreamOperator {
List<Student> list = Student.createStudentList();
public static class Student {
private String name;
private Integer age;
private String address;
public Student(String name, Integer age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
static List<Student> createStudentList() {
return Arrays.asList(
new Student("第七人格", 18, "www.52javaee.com"),
new Student("张三", 18, "北京"),
new Student("李四", 19, "上海"),
new Student("王五", 20, "深圳"),
new Student("赵六", 21, "广州"),
new Student("田七", 22, "杭州")
);
}
}
}
peek
对流中元素进行遍历操作
@Test
public void peek() {
list.stream()
.peek(student -> System.out.println(student.getName()))
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
filter
过滤掉不符合断言判断的数据
@Test
public void filterTest() {
list.stream()
.filter(student -> "第七人格".equals(student.getName()))
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
顺便提一下,filter方法参数声明如下(结合上一章我们学过的Lamda表达式,你get到了吗?)
Stream<T> filter(Predicate<? super T> predicate);
map
将一个元素转换成另一个元素
@Test
public void mapTest() {
list.stream()
.map(Student::getName)
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
flatMap
将一个对象转换成流
@Test
public void flatMapTest() {
list.stream()
.flatMap(student -> Arrays.stream(student.getName().split("")))
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
sort
对流中元素进行排序
@Test
public void sortTest() {
list.stream()
.peek(student -> System.out.println(student.getName()))
.sorted(Comparator.comparing(Student::getAge))
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
skip
跳过前几条记录
@Test
public void skipTest() {
list.stream()
.sorted(Comparator.comparing(Student::getAge))
.skip(5)
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
limit
截断前N条记录
@Test
public void limitTest() {
list.stream()
.sorted(Comparator.comparing(Student::getAge))
.skip(2)
.limit(3)
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
distinct
对流元素进行去重
@Test
public void distinctTest() {
list.stream()
.map(Student::getAge)
.distinct()
.forEach(item -> System.out.println(JSON.toJSONString(item, true)));
}
allMatch
必须所有元素匹配,才返回true
@Test
public void allMatchTest() {
boolean match = list.stream()
.peek(student -> System.out.println(student.getName()))
.allMatch(student -> student.getAge() > 18);
System.out.println(match);
}
anyMatch
只要有任意一个元素匹配,就返回true
@Test
public void anyMatchTest() {
boolean match = list.stream()
.peek(student -> System.out.println(student.getName()))
.anyMatch(student -> student.getAge() > 18);
System.out.println(match);
}
noneMatch
所有元素都不匹配,才返回true
@Test
public void noneMatchTest() {
boolean match = list.stream()
.peek(student -> System.out.println(student.getName()))
.noneMatch(student -> student.getAge() > 18);
System.out.println(match);
}
findFirst
获取第一个元素
@Test
public void findFirstTest() {
Optional<Student> optional = list.stream()
.peek(student -> System.out.println(student.getName()))
.findFirst();
System.out.println(JSON.toJSONString(optional.get(), true));
}
findAny
获取任意一个元素
@Test
public void findAnyTest() {
Optional<Student> optional = list.stream()
.peek(student -> System.out.println(student.getName()))
.findAny();
System.out.println(JSON.toJSONString(optional.get(), true));
}
max
获取最大值
@Test
public void maxTest() {
OptionalDouble optionalDouble = list.stream()
.mapToDouble(Student::getAge)
.max();
System.out.println(optionalDouble.getAsDouble());
}
min
获取最小值
@Test
public void minTest() {
OptionalDouble optionalDouble = list.stream()
.mapToDouble(Student::getAge)
.min();
System.out.println(optionalDouble.getAsDouble());
}
count
获取条数
@Test
public void countTest() {
long count = list.stream().count();
System.out.println(count);
}
总结
本文主要介绍了Java Stream的一些基本概念和常见使用例子。方便新手学习,和老手查找巩固。
下章预告
Java Stream 收集器