目录
[一、Stream 简介](#一、Stream 简介)
[1.1 什么是 Stream?](#1.1 什么是 Stream?)
[1.2 Stream 与集合的区别](#1.2 Stream 与集合的区别)
[1.3 Stream 的操作分类](#1.3 Stream 的操作分类)
[二、Stream 的创建](#二、Stream 的创建)
[2.1 从集合创建](#2.1 从集合创建)
[2.2 从数组创建](#2.2 从数组创建)
[2.3 使用 Stream.of 创建](#2.3 使用 Stream.of 创建)
[2.4 使用 Stream.generate 或 Stream.iterate 创建](#2.4 使用 Stream.generate 或 Stream.iterate 创建)
[三、Stream 的常用操作](#三、Stream 的常用操作)
[3.1 中间操作](#3.1 中间操作)
[3.1.1 filter:过滤](#3.1.1 filter:过滤)
[3.1.2 map:映射](#3.1.2 map:映射)
[3.1.3 sorted:排序](#3.1.3 sorted:排序)
[3.1.4 distinct:去重](#3.1.4 distinct:去重)
[3.1.5 limit 和 skip:限制和跳过](#3.1.5 limit 和 skip:限制和跳过)
[3.2 终端操作](#3.2 终端操作)
[3.2.1 forEach:遍历](#3.2.1 forEach:遍历)
[3.2.2 collect:收集](#3.2.2 collect:收集)
[3.2.3 reduce:归约](#3.2.3 reduce:归约)
[3.2.4 count:计数](#3.2.4 count:计数)
[3.2.5 anyMatch、allMatch、noneMatch:匹配](#3.2.5 anyMatch、allMatch、noneMatch:匹配)
引言
Java 8 引入了 Stream API ,它提供了一种高效且声明式的方式来处理集合数据。Stream API 的核心思想是将数据的操作分为中间操作 和终端操作,并通过流水线(Pipeline)的方式进行处理。Stream API 不仅使代码更加简洁易读,还能充分利用多核处理器的优势,提升数据处理性能。
一、Stream 简介
1.1 什么是 Stream?
Stream 是 Java 8 中处理集合数据的抽象工具。它并不是数据结构,而是一种对数据源(如集合、数组等)进行高效聚合操作的工具。Stream 的特点包括:
-
声明式编程:通过链式调用方法描述数据处理逻辑。
-
惰性求值:中间操作不会立即执行,只有在终端操作触发时才会执行。
-
并行处理:可以轻松实现并行操作,充分利用多核 CPU。
1.2 Stream 与集合的区别
-
集合:存储和操作数据的容器,关注数据的存储和访问。
-
Stream:对数据进行计算和处理的工具,关注数据的计算和转换。
1.3 Stream 的操作分类
Stream 的操作分为两类:
-
中间操作(Intermediate Operations) :返回一个新的 Stream,可以链式调用。例如
filter
、map
、sorted
等。 -
终端操作(Terminal Operations) :触发 Stream 的执行并返回结果。例如
forEach
、collect
、reduce
等。
二、Stream 的创建
Stream 可以从多种数据源创建,例如集合、数组、I/O 资源等。
2.1 从集合创建
java
List<String> list = Arrays.asList("Java", "Python", "C++");
Stream<String> stream = list.stream(); // 创建顺序流
Stream<String> parallelStream = list.parallelStream(); // 创建并行流
2.2 从数组创建
java
String[] array = {"Java", "Python", "C++"};
Stream<String> stream = Arrays.stream(array);
2.3 使用 Stream.of
创建
java
Stream<String> stream = Stream.of("Java", "Python", "C++");
2.4 使用 Stream.generate
或 Stream.iterate
创建
java
// 生成无限流
Stream<String> infiniteStream = Stream.generate(() -> "Hello");
// 生成有限流
Stream<Integer> finiteStream = Stream.iterate(0, n -> n + 1).limit(10);
三、Stream 的常用操作

3.1 中间操作
3.1.1 filter
:过滤
根据条件过滤元素。
java
List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript");
List<String> result = languages.stream()
.filter(s -> s.startsWith("J"))
.collect(Collectors.toList());
System.out.println(result); // 输出 [Java, JavaScript]
3.1.2 map
:映射
将元素转换为另一种形式。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
List<Integer> lengths = languages.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(lengths); // 输出 [4, 6, 3]
3.1.3 sorted
:排序
对元素进行排序。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
List<String> sortedLanguages = languages.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedLanguages); // 输出 [C++, Java, Python]
3.1.4 distinct
:去重
去除重复元素。
java
List<String> languages = Arrays.asList("Java", "Python", "Java", "C++");
List<String> uniqueLanguages = languages.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(uniqueLanguages); // 输出 [Java, Python, C++]
3.1.5 limit
和 skip
:限制和跳过
-
limit(n)
:保留前 n 个元素。 -
skip(n)
:跳过前 n 个元素。
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = numbers.stream()
.limit(3)
.skip(1)
.collect(Collectors.toList());
System.out.println(result); // 输出 [2, 3]
3.2 终端操作
3.2.1 forEach
:遍历
对每个元素执行操作。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
languages.stream().forEach(System.out::println);
3.2.2 collect
:收集
将 Stream 转换为集合或其他数据结构。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
Set<String> languageSet = languages.stream()
.collect(Collectors.toSet());
System.out.println(languageSet); // 输出 [Java, Python, C++]
3.2.3 reduce
:归约
将 Stream 中的元素组合起来,得到一个值。
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println(sum); // 输出 15
3.2.4 count
:计数
返回 Stream 中元素的个数。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
long count = languages.stream().count();
System.out.println(count); // 输出 3
3.2.5 anyMatch
、allMatch
、noneMatch
:匹配
-
anyMatch
:任意一个元素满足条件。 -
allMatch
:所有元素都满足条件。 -
noneMatch
:没有元素满足条件。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
boolean anyMatch = languages.stream().anyMatch(s -> s.startsWith("J"));
boolean allMatch = languages.stream().allMatch(s -> s.length() > 3);
boolean noneMatch = languages.stream().noneMatch(s -> s.isEmpty());
System.out.println(anyMatch); // 输出 true
System.out.println(allMatch); // 输出 false
System.out.println(noneMatch); // 输出 true
四、并行流
Stream API 支持并行处理,只需将 stream()
替换为 parallelStream()
即可。
java
List<String> languages = Arrays.asList("Java", "Python", "C++");
long count = languages.parallelStream()
.filter(s -> s.startsWith("J"))
.count();
System.out.println(count); // 输出 1
五、案例
User实体类
java
public class User {
private int id;
private String userName;
private int age;
//get、set、有参/无参构造器、toString
}
Stream算法题
java
import java.util.Arrays;
import java.util.List;
/*
* 题目:请按照给出数据,找出同时满足以下条件的用户
* 也即以下条件:
* 1、全部满足偶数ID
* 2、年龄大于24
* 3、用户名转为大写
* 4、用户名字母倒排序
* 5、只输出一个用户名字 limit
**/
public class StreamDemo {
public static void main(String[] args) {
User u1 = new User(11, "a", 23);
User u2 = new User(12, "b", 24);
User u3 = new User(13, "c", 22);
User u4 = new User(14, "d", 28);
User u5 = new User(16, "e", 26);
List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
/*
* 1. 首先我们需要将 list 转化为stream流
* 2. 然后将用户过滤出来,这里用到一个函数式接口Predicate<? super T>,我们可
以使用lambda表达式简化
* 3. 这里面传递的参数,就是Stream流的泛型类型,也就是User,所以,这里可以直接
返回用户id为偶数的用户信息;
* 4. 通过forEach进行遍历,直接简化输出 System.out::println ,等价于
System.out.println(u);
**/
//list.stream().filter(u -> {return
//u.getId()%2==0;}).forEach(System.out::println);
//list.stream().filter(u -> {return u.getId()%2==0;})
//.filter(u -> {return
//u.getAge()>24;}).forEach(System.out::println);
//sorted() 自然排序,正排序 D->E
list.stream()
.filter(u -> {return u.getId()%2==0;})
.filter(u -> {return u.getAge()>24;})
.map(u -> {return u.getUserName().toUpperCase();})
//.sorted() //默认正排序 自己用 compareTo 比较
.sorted((o1,o2)->{return o2.compareTo(o1);})
.limit(1)
.forEach(System.out::println);
/*
map解释
List<Integer> list2 = Arrays.asList(1,2,3);
list2 = list2.stream().map(x -> {return
x*2;}).collect(Collectors.toList());
for (Integer element : list2) {
System.out.println(element);
}
*/
}
}
六、总结
Stream API 是 Java 8 中非常强大的工具,它通过声明式的方式简化了集合数据的处理。通过掌握 Stream 的创建、中间操作和终端操作,你可以写出更简洁、高效的代码。以下是本文的核心要点:
-
Stream 的创建:可以从集合、数组、I/O 资源等创建 Stream。
-
中间操作 :如
filter
、map
、sorted
等,用于对数据进行处理和转换。 -
终端操作 :如
forEach
、collect
、reduce
等,用于触发计算并返回结果。 -
并行流 :通过
parallelStream()
实现并行处理,提升性能。