Java 函数式编程之 Lambda 基础详解
引言
在 Java 开发中,单方法接口的匿名类实现常导致代码冗余。Java 8 引入的Lambda 表达式通过简化函数式接口的实现,让代码更简洁优雅。
一、Lambda 表达式基础语法
1. 本质与作用
- 目标:替换单方法接口(如
Comparator
/Runnable
)的匿名类实现 - 核心思想:将函数逻辑直接作为 “参数” 传递,避免冗余的类定义
2. 语法结构
完整形式
(参数列表) -> {
方法体;
return 返回值;
}
示例(传统匿名类 vs Lambda):
// 匿名类实现Comparator
Arrays.sort(array, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
// Lambda表达式
Arrays.sort(array, (s1, s2) -> {
return s1.compareTo(s2);
});
简化形式
若方法体仅一行return
语句,可省略大括号和return
:
Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));
3. 类型推断机制
- 参数类型:编译器自动推断(如
String
类型可省略声明) - 返回值类型:根据方法逻辑自动推导(需与接口抽象方法返回值一致)
二、函数式接口(FunctionalInterface)
1. 定义与标注
- 概念:仅包含一个抽象方法的接口
- 注解:推荐使用
@FunctionalInterface
显式标记(非强制,但可增强代码可读性)
2. 判断规则
-
允许存在:
default
方法(接口默认实现)static
方法(属于接口本身)- 从
Object
继承的方法(如equals()
不计入抽象方法)
-
示例接口:
Comparator
(仅compare()
为抽象方法)Runnable
(仅run()
)Callable<V>
(仅call()
)
3. 接口结构示例
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2); // 唯一抽象方法
default Comparator<T> reversed() { ... } // 允许的default方法
}
三、Lambda vs 匿名类对比
特性 | 匿名类 | Lambda 表达式 |
---|---|---|
代码量 | 冗长(需声明类、方法、返回值) | 简洁(仅保留方法逻辑) |
类型声明 | 必须显式声明参数类型 | 可省略(编译器推断) |
适用场景 | 所有接口(不限于单方法) | 仅适用于FunctionalInterface |
可读性 | 逻辑分散在类结构中 | 聚焦核心业务逻辑 |
典型场景:
当需要传递 “简单行为”(如排序规则、线程任务)时,Lambda 表达式优势显著。
四、实战练习:忽略大小写排序
需求:使用 Lambda 实现字符串数组的忽略大小写排序
代码实现:
String[] array = {"Apple", "orange", "Banana"};
Arrays.sort(array, (s1, s2) -> s1.compareToIgnoreCase(s2));
System.out.println(Arrays.toString(array)); // 输出:[Apple, Banana, orange]
五、核心总结
- Lambda 表达式是 Java 函数式编程的核心特性,专门简化
FunctionalInterface
的实现 - 语法关键:参数列表
->
方法体,利用编译器推断减少样板代码 - 适用场景:所有单方法接口场景(如集合排序、多线程任务、事件监听)
- 最佳实践:配合
@FunctionalInterface
注解明确接口设计意图
Java 方法引用:静态、实例、构造方法引用详解
一、基本概念
定义
当函数式接口的方法签名与现有方法一致时,可直接引用该方法替代 Lambda 表达式,简化代码。
核心逻辑:方法签名需匹配函数式接口的抽象方法(参数类型、数量、返回类型一致,与方法名、类继承无关)。
二、方法引用类型与示例
1. 静态方法引用
-
语法:
类名::静态方法名
-
示例
import java.util.Arrays; public class Main { public static void main(String[] args) { String[] array = {"Apple", "Orange", "Banana", "Lemon"}; Arrays.sort(array, Main::cmp); // 引用静态方法cmp System.out.println(String.join(", ", array)); } static int cmp(String s1, String s2) { return s1.compareTo(s2); // 签名与Comparator.compare一致 } }
2. 实例方法引用
-
语法:
实例对象::实例方法名
或类名::实例方法名
(实例类型作为首个参数) -
原理:实例方法隐含
this
参数,调用时this
作为第一个参数传入。 -
示例
Arrays.sort(array, String::compareTo); // 等价于 (s1, s2) -> s1.compareTo(s2),s1为隐含的this参数
3. 构造方法引用
-
语法:
类名::new
-
示例
import java.util.stream.Collectors; List<String> names = List.of("Bob", "Alice", "Tim"); List<Person> persons = names.stream() .map(Person::new) // 引用Person(String)构造方法,匹配Function<String, Person> .collect(Collectors.toList()); class Person { String name; public Person(String name) { this.name = name; } }
三、关键要点
1. 方法签名匹配规则
- 仅关注参数类型和返回类型,不考虑方法名或类继承关系。
- 示例:
Comparator<String>.compare(String, String)
与String.compareTo(String)
因参数和返回类型一致可匹配。
2. 实例方法的隐含参数
- 实例方法引用时,调用对象(如
String
实例)作为第一个参数传入,等价于将实例方法视为 “扩展参数” 的静态方法。
3. 与 Lambda 的关系
- 方法引用是 Lambda 的语法糖,适用于已有方法满足接口需求的场景,进一步简化代码。
🚀 Java Stream 深度解析:从基础概念到惰性计算实践
Java 8 引入的 Stream API 是函数式编程的核心特性之一,它通过流式操作简化集合处理,支持链式调用和惰性计算。
一、Stream 是什么?
1. 定义与本质
- 所属包:
java.util.stream
,与java.io
流完全不同 - 核心作用:处理 Java 对象序列 的内存计算,支持 有限 / 无限序列
- 核心特性:惰性计算(Lazy Evaluation),仅在需要结果时触发计算
2. 与其他数据结构的对比
特性 | java.io 流 | java.util.List | java.util.stream |
---|---|---|---|
存储类型 | 字节 / 字符序列 | 内存中已存在的对象 | 可能实时计算的对象 |
典型用途 | 序列化 / 文件操作 | 操作已存在的集合 | 流式业务逻辑处理 |
元素数量限制 | 有限 | 有限 | 可无限(惰性计算) |
二、Stream 的核心特点:惰性计算
1. 什么是惰性计算?
-
操作分类:
- 中间操作(如
map
/filter
/limit
):仅定义规则,不触发计算 - 终止操作(如
forEach
/sum
/collect
):触发实际计算
- 中间操作(如
-
执行时机:直到调用终止操作时,才会按规则处理元素
2. 示例:无限序列的惰性处理
// 创建全体自然数的 Stream(未计算)
Stream<BigInteger> naturals = createNaturalStream();
// 转换为平方序列(仍未计算)
Stream<BigInteger> squares = naturals.map(n -> n.multiply(n));
// 截取前100个并打印(触发计算)
squares.limit(100).forEach(System.out::println);
关键点:
- 前两步仅定义转换规则,无实际计算
- 最后一步
forEach
才驱动整个链条执行
三、Stream 核心方法实战
1. 转换操作(中间操作)
-
map(Function<T, R>)
:将元素映射为新类型List<String> names = Arrays.asList("Alice", "Bob"); names.stream() .map(String::toUpperCase) // 转换为大写 .forEach(System.out::println); // 输出:ALICE, BOB
-
filter(Predicate<T>)
:过滤元素List<Integer> numbers = Arrays.asList(1, 2, 3, 4); numbers.stream() .filter(n -> n % 2 == 0) // 保留偶数 .forEach(System.out::println); // 输出:2, 4
-
limit(long n)
:截取前n
个元素
2. 终止操作
-
forEach(Consumer<T>)
:遍历元素 -
reduce()
:聚合计算(如求和)int sum = numbers.stream().reduce(0, Integer::sum); // 计算总和
-
collect(Collectors.toList())
:转换为集合
四、为什么选择 Stream?
1. 优势场景
- 复杂集合处理:链式操作替代多层循环
- 大数据量处理:支持并行流(
parallelStream()
) - 无限序列建模:如数学序列、数据流
2. 注意事项
- 不修改原数据:Stream 操作返回新流,原集合不变
- 一次性消费:流只能使用一次,重复调用需重新创建
Java Stream 创建方式全解析
导语
Java Stream 是函数式编程的核心工具,高效创建 Stream 是使用其强大操作(如 map
、filter
、reduce
)的前提。
一、Stream.of()
:快速创建固定元素 Stream
适用场景:测试或临时创建已知元素的有限 Stream。
语法:Stream.of(元素1, 元素2, ...)
示例代码:
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Stream.of("A", "B", "C", "D");
stream.forEach(System.out::println); // 输出:A B C D
}
}
特点:元素固定,直接传入可变参数,适合少量元素场景。
二、基于数组或 Collection:转换现有数据结构
适用场景:将数组或集合(List
/Set
/Queue
)转换为 Stream 进行处理。
2.1 数组转换
语法:Arrays.stream(数组)
示例代码:
import java.util.Arrays;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Arrays.stream(new String[]{"X", "Y", "Z"});
stream.forEach(System.out::println); // 输出:X Y Z
}
}
2.2 Collection 转换
语法:collection.stream()
示例代码:
import java.util.List;
public class Main {
public static void main(String[] args) {
Stream<String> stream = List.of("Apple", "Banana").stream();
stream.forEach(System.out::println); // 输出:Apple Banana
}
}
特点:基于现有数据结构,元素与原数据一致,支持有限遍历。
三、基于 Supplier:创建无限序列 Stream
适用场景:生成动态、无限序列(如自然数、斐波那契数列)。
语法:Stream.generate(Supplier<T> supplier)
核心逻辑:通过 Supplier.get()
方法实时计算元素,内存占用极低。
示例代码(生成自然数序列):
import java.util.function.Supplier;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<Integer> natural = Stream.generate(new NaturalSupplier());
natural.limit(20).forEach(System.out::println); // 输出 1-20
}
}
class NaturalSupplier implements Supplier<Integer> {
int n = 0;
public Integer get() {
n++;
return n;
}
}
注意:无限序列必须通过 limit()
、findFirst()
等方法转为有限序列,否则会导致死循环!
四、其他 API 方法:文件、字符串分割等
4.1 文件逐行转换(Files.lines()
)
适用场景:按行读取文本文件。
示例代码:
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) throws Exception {
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
lines.forEach(System.out::println); // 逐行输出文件内容
}
}
}
4.2 正则表达式分割(Pattern.splitAsStream()
)
适用场景:将字符串按正则规则分割为 Stream。
示例代码:
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern p = Pattern.compile("\s+");
Stream<String> words = p.splitAsStream("Hello world Java");
words.forEach(System.out::println); // 输出:Hello world Java
}
}
五、基本类型 Stream:IntStream
/LongStream
/DoubleStream
背景:Java 泛型不支持基本类型,装箱拆箱影响性能。
解决方案:使用专用基本类型 Stream:
- 数组转换:
IntStream is = Arrays.stream(new int[]{1, 2, 3});
- 包装类转换:
LongStream ls = list.stream().mapToLong(Long::parseLong);
优势:避免装箱拆箱开销,直接操作基本类型。
总结:5 大创建方式速查表
创建方式 | 核心方法 / API | 适用场景 | 是否有限 |
---|---|---|---|
固定元素 | Stream.of() | 测试、少量已知元素 | 是 |
数组 / 集合转换 | Arrays.stream() / collection.stream() | 处理现有数据结构 | 是 |
无限序列 | Stream.generate(Supplier) | 动态生成、无限数据(需limit ) | 否 |
文件 / 字符串分割 | Files.lines() / Pattern.splitAsStream() | 文本处理、正则分割 | 是 |
基本类型 | IntStream /LongStream | 避免装箱拆箱,提升性能 | 是 / 否 |
Java Stream.map () 用法详解:轻松实现流元素映射转换
一、引言
Stream.map()
是 Java 中 Stream
接口最常用的转换方法之一,用于将一个 Stream
的每个元素映射成另一个元素,并生成一个新的 Stream
。
二、map () 的核心作用
- 本质:将指定函数应用于流的每个元素,实现元素类型转换或数据处理。
- 核心逻辑:对输入流中的每个元素
x
,通过函数f(x)
转换为输出流中的元素f(x)
,形成一一映射关系。
示例图解:
输入流 [1, 2, 3, 4, 5] → 应用函数 f(x)=x² → 输出流 [1, 4, 9, 16, 25]
三、原理:Function 接口与类型转换
map()
方法接收一个 Function
接口对象作为参数,该接口定义了 apply(T t)
方法,用于将 T
类型转换为 R
类型。
方法签名
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Function 接口定义
@FunctionalInterface
public interface Function<T, R> {
R apply(T t); // 将 T 转换为 R
}
关键特性:
- 支持 Lambda 表达式或方法引用简化代码。
- 可实现任意类型转换(如
String → LocalDate
、Integer → String
等)。
四、实战示例
示例 1:数学计算(元素平方)
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> squares = numbers.map(n -> n * n); // 映射为平方数
squares.forEach(System.out::println); // 输出:1 4 9 16 25
}
}
示例 2:字符串处理(去空格 + 转小写)
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List.of(" Apple ", " pear ", " ORANGE", " BaNaNa ")
.stream()
.map(String::trim) // 去除首尾空格
.map(String::toLowerCase) // 转小写
.forEach(System.out::println);
// 输出:apple pear orange banana
}
}
Java Stream.filter () 用法详解:高效过滤流元素的核心方法
导语
在 Java 函数式编程中,Stream.filter()
是Stream
API 中用于数据过滤的核心转换方法。
一、filter () 核心概念
作用
- 对
Stream
中的每个元素执行条件测试 - 过滤掉不满足条件的元素,保留符合条件的元素
- 生成一个新的 Stream(元素数量可能减少)
核心原理
- 接收一个
Predicate
函数式接口作为参数 - 遍历流中的每个元素,执行
Predicate.test(T t)
判断 - 符合条件的元素组成新流,不符合的被 "滤除"
二、使用方法与示例
基础用法:过滤数值流
需求:从整数流中过滤出所有奇数
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
// 过滤条件:n是奇数
.filter(n -> n % 2 != 0)
.forEach(System.out::println); // 输出:1 3 5 7 9
}
}
进阶用法:过滤对象流
需求:从日期流中过滤出所有周末(周六 / 周日)
import java.time.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
// 生成2020年1月的日期流
Stream.generate(new LocalDateSupplier())
.limit(31)
// 过滤条件:是周六或周日
.filter(ldt -> ldt.getDayOfWeek() == DayOfWeek.SATURDAY
|| ldt.getDayOfWeek() == DayOfWeek.SUNDAY)
.forEach(System.out::println); // 输出所有周末日期
}
}
// 日期生成器
class LocalDateSupplier implements Supplier<LocalDate> {
LocalDate start = LocalDate.of(2020, 1, 1);
int n = -1;
public LocalDate get() {
n++;
return start.plusDays(n);
}
}
三、关键接口:Predicate
定义
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t); // 判断元素t是否符合条件
}
使用场景
- 自定义复杂过滤逻辑
- 支持方法引用和 Lambda 表达式
- 可与
and()
、or()
、negate()
组合使用
Java Stream 中的 reduce 方法详解:从基础用法到对象聚合
导语
在 Java 的 Stream 操作中,map()
和filter()
属于转换方法,而reduce()
是重要的聚合方法,用于将流中的所有元素按照指定规则聚合成一个结果。
一、reduce 基础用法:带初始值的聚合
reduce()
最常用的形式是传入初始值和BinaryOperator
函数,该函数定义了元素与累加结果的聚合逻辑。
示例 1:求和
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
// 初始值为0,累加逻辑为acc + n
int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.reduce(0, (acc, n) -> acc + n);
System.out.println(sum); // 输出:45
}
}
执行过程:
- 初始值
acc=0
- 依次对每个元素执行
acc = acc + n
,最终返回累加结果。
示例 2:求积
int product = Stream.of(1, 2, 3, 4, 5)
.reduce(1, (acc, n) -> acc * n); // 初始值必须为1
System.out.println(product); // 输出:120
二、无初始值:返回 Optional 对象
若不传入初始值,reduce()
会返回Optional
类型,以处理流中元素可能为 0 的情况(避免空指针异常)。
Stream<Integer> stream = Stream.of(1, 2, 3);
Optional<Integer> optSum = stream.reduce((acc, n) -> acc + n);
optSum.ifPresent(result -> System.out.println("结果:" + result)); // 输出:6
注意:若流为空,Optional
将返回空值,需通过isPresent()
或ifPresent()
判断。
三、对象聚合:将配置行转换为 Map
reduce()
不仅适用于数值计算,还可用于聚合 Java 对象。以下示例将配置文件的每行字符串转换为Map<String, String>
:
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> props = List.of("profile=native", "debug=true", "logging=warn");
Map<String, String> config = props.stream()
// 第一步:将每个字符串映射为单个键值对Map
.map(kv -> {
String[] arr = kv.split("=", 2);
return Map.of(arr[0], arr[1]); // Java 9+可用Map.of
})
// 第二步:将所有小Map合并为一个大Map
.reduce(new HashMap<>(), (m, kv) -> {
m.putAll(kv);
return m;
});
config.forEach((k, v) -> System.out.println(k + "=" + v));
}
}
输出结果:
profile=native
debug=true
logging=warn
四、核心原理与注意事项
-
BinaryOperator
接口:
定义为T apply(T t, T u)
,用于接收前一次结果acc
和当前元素n
,返回新的累加结果。 -
流的一次性特性:
流中的元素只能被操作一次,聚合操作(如reduce
)会触发流的遍历,后续无法重复使用该流。 -
初始值的作用:
- 作为聚合的起点(如求和用
0
,求积用1
)。 - 决定返回值类型(带初始值返回具体类型,不带则返回
Optional
)。
- 作为聚合的起点(如求和用
Java Stream 输出集合:从转换到聚合的完整实践
引言
在 Java 中使用 Stream
时,操作可分为两类:
- 转换操作(如
map()
、filter()
):仅定义规则,不触发实际计算,返回新的Stream
。 - 聚合操作(如
reduce()
、collect()
):触发链式计算,返回具体结果或集合。
一、输出为 List
核心方法:collect(Collectors.toList())
作用:过滤元素后收集到 List
中。
示例:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
// 原始 Stream(包含空字符串、null)
Stream<String> stream = Stream.of("Apple", "", null, "Pear", " ", "Orange");
// 过滤非空字符串并收集到 List
List<String> list = stream
.filter(s -> s != null && !s.isBlank()) // 过滤条件
.collect(Collectors.toList()); // 收集为 List
System.out.println(list); // 输出:[Apple, Pear, Orange]
}
}
二、输出为数组
核心方法:toArray(数组构造方法)
作用:将 Stream
元素转为指定类型数组。
示例:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> list = List.of("Apple", "Banana", "Orange");
// 转为 String 数组
String[] array = list.stream()
.toArray(String[]::new); // 传入数组构造方法
System.out.println(Arrays.toString(array)); // 输出:[Apple, Banana, Orange]
}
}
三、输出为 Map
核心方法:collect(Collectors.toMap(keyMapper, valueMapper))
作用:将元素映射为 key-value
对存入 Map
。
示例:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Stream.of("APPL:Apple", "MSFT:Microsoft");
// 按冒号分割字符串,前半部分为 key,后半部分为 value
Map<String, String> map = stream.collect(Collectors.toMap(
s -> s.substring(0, s.indexOf(':')), // key 映射
s -> s.substring(s.indexOf(':') + 1) // value 映射
));
System.out.println(map); // 输出:{APPL=Apple, MSFT=Microsoft}
}
}
四、分组输出
核心方法:collect(Collectors.groupingBy(分组键映射, 收集器))
作用:按指定规则分组,每组元素存入 List
或其他集合。
示例:按字符串首字母分组:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> list = List.of("Apple", "Banana", "Blackberry", "Coconut", "Avocado", "Cherry", "Apricots");
// 按首字母分组,结果为 Map<String, List<String>>
Map<String, List<String>> groups = list.stream()
.collect(Collectors.groupingBy(
s -> s.substring(0, 1), // 分组键:首字母
Collectors.toList() // 每组收集为 List
));
System.out.println(groups);
/* 输出:
{
A=[Apple, Avocado, Apricots],
B=[Banana, Blackberry],
C=[Coconut, Cherry]
}
*/
}
}
Java Stream 高级操作详解:排序、去重、合并与并行处理
导语
Java Stream 提供了丰富的操作方法,除基础的 map
、filter
外,其高级操作如排序、去重、合并等能高效处理集合数据。
一、排序操作(sorted()
)
1. 自然排序
需元素实现 Comparable
接口,直接调用 sorted()
:
List<String> list = List.of("Orange", "apple", "Banana")
.stream()
.sorted()
.collect(Collectors.toList()); // [Banana, Orange, apple]
2. 自定义排序
通过 Comparator
定制排序规则:
List<String> list = List.of("Orange", "apple", "Banana")
.stream()
.sorted(String::compareToIgnoreCase) // 忽略大小写排序
.collect(Collectors.toList()); // [apple, Banana, Orange]
注意:sorted()
是转换操作,返回新 Stream
。
二、去重操作(distinct()
)
基于元素的 equals()
方法去重,直接调用 distinct()
:
List.of("A", "B", "A", "C", "B", "D")
.stream()
.distinct()
.collect(Collectors.toList()); // [A, B, C, D]
三、截取操作(skip()
/limit()
)
skip(n)
:跳过前n
个元素limit(n)
:保留前n
个元素
示例:
List.of("A", "B", "C", "D", "E", "F")
.stream()
.skip(2) // 跳过 A、B
.limit(3) // 截取 C、D、E
.collect(Collectors.toList()); // [C, D, E]
四、合并操作(concat()
/flatMap()
)
1. 简单合并(concat()
)
合并两个 Stream
:
Stream<String> s1 = List.of("A", "B", "C").stream();
Stream<String> s2 = List.of("D", "E").stream();
Stream.concat(s1, s2).collect(Collectors.toList()); // [A, B, C, D, E]
2. 深度合并(flatMap()
)
将 Stream
中的嵌套集合展开为单一 Stream
:
Stream<List<Integer>> nestedList = Stream.of(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5, 6)
);
Stream<Integer> flatList = nestedList.flatMap(list -> list.stream()); // 1,2,3,4,5,6
五、并行处理(parallel()
)
通过 parallel()
将 Stream
转为并行流,自动利用多线程加速处理(适用于大数据集):
String[] result = Stream.of("a", "b", "c", "d")
.parallel() // 并行处理
.sorted()
.toArray(String[]::new);
六、聚合与匹配操作
1. 聚合方法
count()
:统计元素个数max(Comparator)
/min(Comparator)
:求最值sum()
/average()
:数值流求和、平均值(仅适用于IntStream
/LongStream
/DoubleStream
) 示例:
IntStream.of(1, 2, 3, 4, 5)
.sum(); // 15
DoubleStream.of(1.1, 2.2, 3.3)
.average(); // OptionalDouble[2.2]
2. 匹配方法
allMatch(Predicate)
:所有元素满足条件返回true
anyMatch(Predicate)
:至少一个元素满足条件返回true
boolean allEven = IntStream.of(2, 4, 6).allMatch(n -> n % 2 == 0); // true
boolean hasEven = IntStream.of(1, 3, 5).anyMatch(n -> n % 2 == 0); // false
3. 遍历操作(forEach()
)
终端操作,遍历元素执行消费逻辑:
Stream.of("apple", "banana")
.forEach(System.out::println); // 输出每个元素
七、操作分类小结
操作类型 | 具体方法 |
---|---|
转换操作 | map 、filter 、sorted 、distinct 、skip 、limit |
合并操作 | concat 、flatMap |
并行处理 | parallel |
聚合操作 | reduce 、collect 、count 、max 、min 、sum 、average |
其他操作 | allMatch 、anyMatch 、forEach |