文章目录
一、概念
Java 的 Stream流
是 Java 8 引入的一个重要特性,用于对集合数据进行高效、简洁的操作和处理。
Stream流
具有以下一些特点和优势:
- 声明式编程风格:可以通过一系列的方法调用来描述对数据的操作,而无需关注具体的实现细节。
- 链式操作:可以将多个操作链接在一起,形成一个处理流水线,提高代码的可读性和简洁性。
- 并行处理:
Stream流
支持并行操作,能够充分利用多核 CPU 的优势,提高数据处理的效率。
使用 Stream流
的步骤如下:
- 创建一个集合的
Stream流
。 - 使用一系列
中间操作
来对元素进行处理和转换。 - 最后使用
终结操作
来获取结果。
二、创建流
2.1 单列集合
- 集合对象.stream()。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 创建Stream流
list.stream();
}
}
2.2 数组
- Arrays.stream(数组),注意数组的类型要用包装类。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
// 创建数组
Integer[] arr = {1, 2 , 3 , 4 , 5};
// 创建Stream流
Arrays.stream(arr);
}
}
2.3 双列集合
- 获取map对象的键值对对象,在调用stream()。
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
// 创建集合
HashMap<String, Object> map = new HashMap<>();
// 创建Stream流
Stream<Map.Entry<String, Object>> stream = map.entrySet().stream();
}
}
三、中间操作
3.1 filter
- 对集合中的元素过滤,符合条件的才会留下来。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊");
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("欧阳天天");
// 创建Stream流
list.stream()
.filter(name -> name.length() == 3) // 筛选集合中元素长度等于3的元素
.forEach(name -> System.out.println(name)); // 打印集合元素
}
}
运行结果:
张三丰
张无忌
周芷若
3.2 map
- 对集合中的元素计算或者转换类型。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("12");
list.add("16");
list.add("25");
list.add("31");
list.add("11");
list.add("18");
// 创建Stream流
list.stream()
.map(age -> Integer.parseInt(age)) // 将元素转换成Integer类型
.map(age -> age + 2) // 将集合中所有元素 +2
.forEach(age -> System.out.println(age)); // 打印集合
}
}
运行结果:
14
18
27
33
13
20
3.3 distinct
- 对集合元素进行去重。需要注意的是它是通过
Object
父类的hashCode()
和equals()
来去重的,所以如果是自定义类,就需要重写Object
父类的hashCode()
和equals()
方法。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊");
list.add("张三丰");
list.add("张三丰");
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("欧阳天天");
// 创建Stream流
list.stream()
.distinct() // 对元素去重
.forEach(name -> System.out.println(name)); // 打印集合元素
}
}
运行结果:
石昊
张三丰
张无忌
周芷若
赵敏
欧阳天天
3.4 sorted
- 对集合元素进行排序。
- 需要注意的是sorted()有两种实现方法,
- 一种是空参的,默认是升序,如果集合中的元素是自定义类,那么需要在类上添加
Comparable
接口,否则会报错; - 一种是有参的,可以使用
Lmabda表达式
来实现Comparator
接口,然后在流中使用。
- 一种是空参的,默认是升序,如果集合中的元素是自定义类,那么需要在类上添加
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(1);
list.add(5);
list.add(3);
list.add(2);
list.add(9);
// 创建Stream流
list.stream()
.sorted((o1, o2) -> o2 - o1) // 对元素进行降序排列,从大到小
.forEach(num -> System.out.println(num)); // 打印集合元素
}
}
运行结果:
9
5
3
2
1
3.5 limit
- 获取集合的前几个元素。
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊");
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("欧阳天天");
// 创建Stream流
list.stream()
.limit(3) // 获取前三个元素
.forEach(name -> System.out.println(name)); // 打印集合元素
}
}
运行结果
石昊
张三丰
张无忌
3.6 skip
- 跳过集合的前几个元素。
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊");
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("欧阳天天");
// 创建Stream流
list.stream()
.skip(3) // 跳过前三个元素
.forEach(name -> System.out.println(name)); // 打印集合元素
}
}
运行结果:
周芷若
照明
欧阳天天
三、终结操作
4.1 forEach
- 对集合元素进行遍历操作。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊");
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("欧阳天天");
// 创建Stream流
list.stream()
.filter(name -> name.length() == 2) // 筛选出集合中长度等于2的元素
.forEach(name -> System.out.println(name)); // 打印集合元素
}
}
运行结果:
石昊
赵敏
4.2 count
- 统计集合元素的个数。
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊");
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("欧阳天天");
// 创建Stream流
long count = list.stream()
.filter(name -> name.length() == 2) // 筛选出集合中长度等于2的元素
.count(); // 获取集合元素的个数
System.out.println("个数:" + count);
}
}
运行结果:
个数:2
4.3 max
- 返回集合中最大的元素
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(12);
list.add(24);
list.add(32);
list.add(44);
list.add(56);
// 创建Stream流
Optional<Integer> max = list.stream()
.max(((o1, o2) -> o1 - o2));// 返回集合中最大的数字
System.out.println("集合最大的元素是:" + max.get());
}
}
运行结果:
集合最大的元素是:56
4.4 min
- 返回集合中最小的元素
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(12);
list.add(24);
list.add(32);
list.add(44);
list.add(56);
// 创建Stream流
Optional<Integer> min = list.stream()
.min(((o1, o2) -> o1 - o2));// 返回集合中最大的数字
System.out.println("集合最小的元素是:" + min.get());
}
}
运行结果:
集合最小的元素是:12
4.5 collect
- 将集合中的元素转成
List
、Set
或Map
集合。
List 集合
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊-12");
list.add("张三丰-121");
list.add("张无忌-42");
list.add("周芷若-21");
list.add("赵敏-22");
list.add("欧阳天天-33");
// 创建Stream流
List<String> collect = list.stream()
.map(name -> name.split("-")[0]) // 将集合中的姓名分割出来
.collect(Collectors.toList()); // 将结果转成List集合
System.out.println("新集合:" + collect);
}
}
运行结果:
新集合:[石昊, 张三丰, 张无忌, 周芷若, 赵敏, 欧阳天天]
Set 集合
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊-12");
list.add("张三丰-121");
list.add("张无忌-42");
list.add("周芷若-21");
list.add("赵敏-22");
list.add("欧阳天天-33");
// 创建Stream流
Set<String> collect = list.stream()
.map(name -> name.split("-")[0]) // 将集合中的姓名分割出来
.collect(Collectors.toSet()); // 将结果转成List集合
System.out.println("新集合:" + collect);
}
}
运行结果:
新集合:[欧阳天天, 石昊, 张三丰, 周芷若, 赵敏, 张无忌]
map 集合
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("石昊-12");
list.add("张三丰-121");
list.add("张无忌-42");
list.add("周芷若-21");
list.add("赵敏-22");
list.add("欧阳天天-33");
// 创建Stream流
Map<String, Integer> collect = list.stream()
// 将集合元素的姓名作为key,年龄作为value,返回一个map集合
.collect(Collectors.toMap(name -> name.split("-")[0], age -> Integer.parseInt(age.split("-")[1])));
System.out.println("新集合:" + collect);
}
}
运行结果:
新集合:{欧阳天天=33, 石昊=12, 张三丰=121, 周芷若=21, 赵敏=22, 张无忌=42}
4.6 anyMatch
- 判断集合是否满足条件,结果为
boolean
类型
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(35);
list.add(12);
list.add(32);
list.add(12);
list.add(42);
// 创建Stream流
boolean flag = list.stream()
.anyMatch(num -> num > 35);// 判断集合中是否存在大于35的元素
System.out.println(flag);
}
}
运行结果
true
4.6 allMatch
- 判断集合中的元素是否全部都满足条件,结果为
boolean
类型
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(35);
list.add(12);
list.add(32);
list.add(12);
list.add(42);
// 创建Stream流
boolean flag = list.stream()
.allMatch(num -> num > 35); // 判断集合中是否全部都大于35
System.out.println(flag);
}
}
运行结果
false
4.7 findAny
- 返回集合中随机的元素。
在串行流中,findAny方法很可能返回流中的第一个元素,但这并不是确定的,因为它可以自由选择流中的任何元素。而在并行流中,findAny方法会返回最先处理完的元素,这可能不是第一个元素。
import java.util.ArrayList;
import java.util.Optional;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(35);
list.add(12);
list.add(32);
list.add(12);
list.add(42);
// 创建Stream流
Optional<Integer> optionalI = list.stream()
.findAny(); // 获取集合中任意的元素
// 如果存在该元素,就输出
optionalI.ifPresent(num -> System.out.println(num));
}
}
运行结果
35
4.8 findFirst
- 返回集合中第一个元素。
import java.util.ArrayList;
import java.util.Optional;
public class Test {
public static void main(String[] args) {
// 创建集合
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(12);
list.add(32);
list.add(35);
list.add(12);
list.add(42);
// 创建Stream流
Optional<Integer> optionalI = list.stream()
.findFirst(); // 获取集合中第一个元素
// 如果存在该元素,就输出
optionalI.ifPresent(num -> System.out.println(num));
}
}
运行结果
12
五、注意事项
- 中间操作会返回新的
Stream流
,推荐使用链式编程去调用方法; - 如果对
Stream流
执行了终结操作,那么就无法再对原先的Stream流
进行操作,只能重新创建一个新的流; - 修改
Stream流
中的数据,不会影响到原来的集合或数组。