引言:Java的函数式编程革命
在Java 8之前,Java一直被诟病为"过于冗长"的语言。函数式编程的引入彻底改变了这一局面,让Java代码变得更加简洁、表达力更强。Lambda表达式不仅仅是语法糖,它代表了Java编程范式的一次重大转变。
Lambda表达式基础:从匿名类到Lambda
传统的匿名内部类
java
// Java 8之前的方式
public class TraditionalExample {
public static void main(String[] args) {
// 创建Runnable的匿名实现
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("传统方式:线程运行中...");
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
Lambda表达式简化
java
// Java 8 Lambda表达式
public class LambdaExample {
public static void main(String[] args) {
// 使用Lambda表达式
Runnable runnable = () -> System.out.println("Lambda方式:线程运行中...");
Thread thread = new Thread(runnable);
thread.start();
// 甚至可以更简洁
new Thread(() -> System.out.println("最简Lambda表达式")).start();
}
}
函数式接口:Lambda的类型基础
什么是函数式接口?
函数式接口是只有一个抽象方法的接口,可以使用@FunctionalInterface注解标记。
java
// 自定义函数式接口
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
// 可以有默认方法
default void printResult(int result) {
System.out.println("结果:" + result);
}
// 可以有静态方法
static void printInfo() {
System.out.println("这是一个计算器接口");
}
}
// 使用自定义函数式接口
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
// 加法实现
Calculator addition = (a, b) -> a + b;
System.out.println("加法:" + addition.calculate(5, 3));
// 减法实现
Calculator subtraction = (a, b) -> a - b;
System.out.println("减法:" + subtraction.calculate(5, 3));
// 乘法实现
Calculator multiplication = (a, b) -> a * b;
multiplication.printResult(multiplication.calculate(5, 3));
// 调用静态方法
Calculator.printInfo();
}
}
Java内置的函数式接口
Java 8在java.util.function包中提供了丰富的函数式接口:
java
import java.util.function.*;
public class BuiltInFunctionalInterfaces {
public static void main(String[] args) {
// 1. Predicate<T> - 断言,返回布尔值
Predicate<String> isNotEmpty = s -> s != null && !s.isEmpty();
System.out.println("字符串是否非空:" + isNotEmpty.test("Hello"));
// 2. Function<T, R> - 函数,接受T返回R
Function<String, Integer> stringLength = String::length;
System.out.println("字符串长度:" + stringLength.apply("Java"));
// 3. Consumer<T> - 消费者,接受T无返回值
Consumer<String> printer = System.out::println;
printer.accept("你好,Java!");
// 4. Supplier<T> - 供应者,无参返回T
Supplier<Double> randomSupplier = Math::random;
System.out.println("随机数:" + randomSupplier.get());
// 5. UnaryOperator<T> - 一元操作,继承Function<T, T>
UnaryOperator<String> toUpperCase = String::toUpperCase;
System.out.println("大写:" + toUpperCase.apply("java"));
// 6. BinaryOperator<T> - 二元操作,继承BiFunction<T, T, T>
BinaryOperator<Integer> max = Math::max;
System.out.println("最大值:" + max.apply(10, 20));
}
// 函数式接口的组合
public static void functionComposition() {
Function<Integer, Integer> multiplyBy2 = x -> x * 2;
Function<Integer, Integer> add3 = x -> x + 3;
// 组合函数:先乘2再加3
Function<Integer, Integer> multiplyThenAdd = multiplyBy2.andThen(add3);
System.out.println("5 * 2 + 3 = " + multiplyThenAdd.apply(5));
// 组合函数:先加3再乘2
Function<Integer, Integer> addThenMultiply = multiplyBy2.compose(add3);
System.out.println("(5 + 3) * 2 = " + addThenMultiply.apply(5));
// Predicate的组合
Predicate<String> startsWithJ = s -> s.startsWith("J");
Predicate<String> endsWithA = s -> s.endsWith("a");
Predicate<String> startsWithJAndEndsWithA = startsWithJ.and(endsWithA);
System.out.println("Java是否符合:" + startsWithJAndEndsWithA.test("Java"));
Predicate<String> startsWithJOrEndsWithA = startsWithJ.or(endsWithA);
System.out.println("Python是否符合:" + startsWithJOrEndsWithA.test("Python"));
}
}
方法引用:让Lambda更简洁
方法引用是Lambda表达式的简写形式,共有四种类型:
java
import java.util.Arrays;
import java.util.List;
public class MethodReferenceExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 1. 静态方法引用
names.forEach(System.out::println);
// 2. 实例方法引用(特定对象的实例方法)
String prefix = "Mr. ";
names.forEach(prefix::concat); // 等同于 s -> prefix.concat(s)
// 3. 实例方法引用(任意对象的实例方法)
names.forEach(String::toUpperCase); // 等同于 s -> s.toUpperCase()
// 4. 构造器引用
List<String> strings = Arrays.asList("1", "2", "3");
List<Integer> numbers = strings.stream()
.map(Integer::new) // 等同于 s -> new Integer(s)
.toList();
}
// 方法引用的实际应用
public static void practicalExamples() {
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 20)
);
// 按年龄排序(使用Comparator.comparing和实例方法引用)
people.sort(Comparator.comparing(Person::getAge));
// 提取所有名字
List<String> names = people.stream()
.map(Person::getName) // 实例方法引用
.toList();
// 创建新Person列表(使用构造器引用)
List<Person> clonedPeople = people.stream()
.map(Person::new) // 复制构造器
.toList();
}
static class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 复制构造器
public Person(Person other) {
this.name = other.name;
this.age = other.age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
}
Stream API:集合的函数式操作
Stream API是Java 8引入的最重要特性之一,它提供了对集合数据的函数式处理能力。
Stream的基本操作
java
import java.util.*;
import java.util.stream.*;
public class StreamAPIExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 1. 创建Stream
Stream<Integer> stream1 = numbers.stream(); // 从集合创建
Stream<String> stream2 = Stream.of("A", "B", "C"); // 直接创建
Stream<Integer> stream3 = Stream.iterate(0, n -> n + 1).limit(10); // 无限流
// 2. 中间操作(返回新Stream)
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0) // 过滤偶数
.map(n -> n * 2) // 每个元素乘以2
.sorted((a, b) -> b - a) // 倒序排序
.collect(Collectors.toList()); // 收集结果
System.out.println("处理后的偶数:" + evenNumbers);
// 3. 终端操作(产生结果或副作用)
long count = numbers.stream().count();
Optional<Integer> max = numbers.stream().max(Integer::compare);
Optional<Integer> min = numbers.stream().min(Integer::compare);
Integer sum = numbers.stream().reduce(0, Integer::sum);
System.out.println("总数:" + count);
System.out.println("最大值:" + max.orElse(0));
System.out.println("最小值:" + min.orElse(0));
System.out.println("总和:" + sum);
}
// 更复杂的Stream操作
public static void advancedStreamOperations() {
List<Student> students = Arrays.asList(
new Student("Alice", Arrays.asList("Math", "Physics", "Chemistry")),
new Student("Bob", Arrays.asList("Math", "Biology", "History")),
new Student("Charlie", Arrays.asList("Physics", "Chemistry", "Computer Science"))
);
// 获取所有不重复的课程
List<String> allCourses = students.stream()
.flatMap(student -> student.getCourses().stream()) // 扁平化
.distinct() // 去重
.sorted() // 排序
.collect(Collectors.toList());
System.out.println("所有课程:" + allCourses);
// 分组操作:按课程长度分组
Map<Integer, List<String>> groupedByLength = allCourses.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println("按长度分组:" + groupedByLength);
// 分区操作:区分长课程和短课程
Map<Boolean, List<String>> partitioned = allCourses.stream()
.collect(Collectors.partitioningBy(course -> course.length() > 10));
System.out.println("长课程:" + partitioned.get(true));
System.out.println("短课程:" + partitioned.get(false));
// 统计信息
IntSummaryStatistics stats = students.stream()
.mapToInt(student -> student.getCourses().size())
.summaryStatistics();
System.out.println("课程数统计:");
System.out.println(" 平均:" + stats.getAverage());
System.out.println(" 最多:" + stats.getMax());
System.out.println(" 最少:" + stats.getMin());
System.out.println(" 总数:" + stats.getSum());
}
// 并行Stream
public static void parallelStreamExample() {
List<Integer> numbers = IntStream.rangeClosed(1, 1000000)
.boxed()
.collect(Collectors.toList());
long startTime = System.currentTimeMillis();
long sequentialSum = numbers.stream()
.mapToLong(Integer::longValue)
.sum();
long sequentialTime = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();
long parallelSum = numbers.parallelStream()
.mapToLong(Integer::longValue)
.sum();
long parallelTime = System.currentTimeMillis() - startTime;
System.out.println("顺序流耗时:" + sequentialTime + "ms");
System.out.println("并行流耗时:" + parallelTime + "ms");
System.out.println("加速比:" + (double) sequentialTime / parallelTime);
// 注意:并行流并不总是更快,需要考虑:
// 1. 数据量是否足够大
// 2. 操作是否足够耗时
// 3. 是否容易分割
}
static class Student {
private String name;
private List<String> courses;
public Student(String name, List<String> courses) {
this.name = name;
this.courses = courses;
}
public String getName() { return name; }
public List<String> getCourses() { return courses; }
}
}
Optional:优雅处理null值
Optional是Java 8引入的容器类,用于包装可能为null的值。
java
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
// 创建Optional对象
Optional<String> optional1 = Optional.of("Hello"); // 值不能为null
Optional<String> optional2 = Optional.ofNullable(null); // 值可以为null
Optional<String> optional3 = Optional.empty(); // 空Optional
// 传统null检查方式
String traditionalResult = getTraditionalValue();
if (traditionalResult != null) {
System.out.println("传统方式:" + traditionalResult.toUpperCase());
}
// Optional方式
Optional<String> optionalValue = getOptionalValue();
optionalValue.ifPresent(value ->
System.out.println("Optional方式:" + value.toUpperCase()));
// 链式操作
String result = getOptionalValue()
.map(String::toUpperCase)
.filter(s -> s.length() > 3)
.orElse("默认值");
System.out.println("链式操作结果:" + result);
// 更复杂的链式操作
Person person = new Person("Alice",
Optional.of(new Address(
Optional.of("Main Street"),
"New York")));
String street = person.getAddress()
.flatMap(Address::getStreet)
.orElse("未知街道");
System.out.println("街道:" + street);
}
// 实际应用:避免深层null检查
public static void processUser(User user) {
// 传统方式(繁琐且容易出错)
if (user != null) {
Profile profile = user.getProfile();
if (profile != null) {
Address address = profile.getAddress();
if (address != null) {
String city = address.getCity();
if (city != null) {
System.out.println(city.toUpperCase());
}
}
}
}
// Optional方式(简洁安全)
Optional.ofNullable(user)
.map(User::getProfile)
.map(Profile::getAddress)
.map(Address::getCity)
.ifPresent(city -> System.out.println(city.toUpperCase()));
}
// 示例方法
public static String getTraditionalValue() {
return Math.random() > 0.5 ? "Hello" : null;
}
public static Optional<String> getOptionalValue() {
return Math.random() > 0.5 ? Optional.of("Hello") : Optional.empty();
}
static class Person {
private String name;
private Optional<Address> address;
public Person(String name, Optional<Address> address) {
this.name = name;
this.address = address;
}
public Optional<Address> getAddress() {
return address;
}
}
static class Address {
private Optional<String> street;
private String city;
public Address(Optional<String> street, String city) {
this.street = street;
this.city = city;
}
public Optional<String> getStreet() {
return street;
}
public String getCity() {
return city;
}
}
// 演示用的类
static class User {
private Profile profile;
public Profile getProfile() { return profile; }
}
static class Profile {
private Address address;
public Address getAddress() { return address; }
}
}
实战:重构传统代码为函数式风格
案例1:处理订单列表
java
import java.util.*;
import java.util.stream.*;
public class OrderProcessor {
// 传统方式
public static class TraditionalOrderProcessor {
public double calculateTotalRevenue(List<Order> orders) {
double total = 0;
for (Order order : orders) {
if (order.getStatus() == OrderStatus.COMPLETED) {
for (OrderItem item : order.getItems()) {
total += item.getPrice() * item.getQuantity();
}
}
}
return total;
}
public List<String> getCustomerNames(List<Order> orders) {
List<String> names = new ArrayList<>();
for (Order order : orders) {
String name = order.getCustomerName();
if (name != null && !names.contains(name)) {
names.add(name);
}
}
Collections.sort(names);
return names;
}
}
// 函数式方式
public static class FunctionalOrderProcessor {
public double calculateTotalRevenue(List<Order> orders) {
return orders.stream()
.filter(order -> order.getStatus() == OrderStatus.COMPLETED)
.flatMap(order -> order.getItems().stream())
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum();
}
public List<String> getCustomerNames(List<Order> orders) {
return orders.stream()
.map(Order::getCustomerName)
.filter(Objects::nonNull)
.distinct()
.sorted()
.collect(Collectors.toList());
}
// 更多函数式操作示例
public Map<OrderStatus, Long> countOrdersByStatus(List<Order> orders) {
return orders.stream()
.collect(Collectors.groupingBy(
Order::getStatus,
Collectors.counting()
));
}
public Optional<Order> findMostExpensiveOrder(List<Order> orders) {
return orders.stream()
.max(Comparator.comparingDouble(order ->
order.getItems().stream()
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum()
));
}
public Map<String, Double> getCustomerTotalSpent(List<Order> orders) {
return orders.stream()
.filter(order -> order.getStatus() == OrderStatus.COMPLETED)
.collect(Collectors.groupingBy(
Order::getCustomerName,
Collectors.summingDouble(order ->
order.getItems().stream()
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum()
)
));
}
}
// 实体类
enum OrderStatus { PENDING, PROCESSING, COMPLETED, CANCELLED }
static class Order {
private String customerName;
private OrderStatus status;
private List<OrderItem> items;
public String getCustomerName() { return customerName; }
public OrderStatus getStatus() { return status; }
public List<OrderItem> getItems() { return items; }
}
static class OrderItem {
private String productName;
private double price;
private int quantity;
public double getPrice() { return price; }
public int getQuantity() { return quantity; }
}
}
案例2:构建数据处理管道
java
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class DataProcessingPipeline {
// 构建可重用的数据处理管道
public static class PipelineBuilder<T, R> {
private List<Function<T, T>> processors = new ArrayList<>();
private Function<T, R> finisher;
public PipelineBuilder<T, R> addProcessor(Function<T, T> processor) {
processors.add(processor);
return this;
}
public PipelineBuilder<T, R> setFinisher(Function<T, R> finisher) {
this.finisher = finisher;
return this;
}
public R process(T input) {
T result = input;
for (Function<T, T> processor : processors) {
result = processor.apply(result);
}
return finisher.apply(result);
}
// 使用Stream构建更灵活的管道
public static <T, R> Function<T, R> buildPipeline(
List<Function<T, T>> processors,
Function<T, R> finisher) {
return input -> {
T result = input;
for (Function<T, T> processor : processors) {
result = processor.apply(result);
}
return finisher.apply(result);
};
}
}
// 实际应用:文本处理管道
public static void textProcessingExample() {
// 构建文本处理管道
Function<String, String> textPipeline = PipelineBuilder.buildPipeline(
Arrays.asList(
String::trim, // 1. 去除首尾空格
s -> s.replaceAll("\s+", " "), // 2. 合并多个空格
String::toLowerCase, // 3. 转为小写
s -> s.replaceAll("[^a-z0-9\s]", "") // 4. 移除非字母数字
),
String::toString // 最终处理
);
String input = " Hello, WORLD!! This is a TEST. ";
String output = textPipeline.apply(input);
System.out.println("输入: " + input);
System.out.println("输出: " + output);
}
// 实际应用:数字处理管道
public static void numberProcessingExample() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 构建数字处理管道
Function<List<Integer>, Map<String, Object>> numberPipeline =
PipelineBuilder.buildPipeline(
Arrays.asList(
list -> list.stream() // 转为Stream
.filter(n -> n % 2 == 0) // 过滤偶数
.collect(Collectors.toList()),
list -> list.stream() // 再次转为Stream
.map(n -> n * n) // 平方
.collect(Collectors.toList())
),
list -> {
// 计算各种统计信息
IntSummaryStatistics stats = list.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
Map<String, Object> result = new HashMap<>();
result.put("数据", list);
result.put("总和", stats.getSum());
result.put("平均值", stats.getAverage());
result.put("最大值", stats.getMax());
result.put("最小值", stats.getMin());
result.put("数量", stats.getCount());
return result;
}
);
Map<String, Object> result = numberPipeline.apply(numbers);
System.out.println("处理结果:");
result.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
性能优化与最佳实践
Lambda表达式的性能考虑
java
public class LambdaPerformance {
// 基准测试:Lambda vs 匿名内部类
public static void performanceComparison() {
int iterations = 1000000;
// 测试Lambda表达式
long lambdaStart = System.nanoTime();
for (int i = 0; i < iterations; i++) {
Runnable lambda = () -> System.out.println("Lambda");
}
long lambdaTime = System.nanoTime() - lambdaStart;
// 测试匿名内部类
long anonStart = System.nanoTime();
for (int i = 0; i < iterations; i++) {
Runnable anon = new Runnable() {
@Override
public void run() {
System.out.println("Anonymous");
}
};
}
long anonTime = System.nanoTime() - anonStart;
System.out.println("Lambda创建时间: " + lambdaTime + " ns");
System.out.println("匿名类创建时间: " + anonTime + " ns");
System.out.println("性能差异: " + (anonTime - lambdaTime) + " ns");
}
// Stream的性能优化
public static void streamPerformanceTips() {
List<Integer> numbers = IntStream.rangeClosed(1, 1000000)
.boxed()
.collect(Collectors.toList());
// 性能陷阱1:频繁装箱拆箱
long slowSum = numbers.stream()
.reduce(0, (a, b) -> a + b); // 每次操作都有装箱拆箱
long fastSum = numbers.stream()
.mapToInt(Integer::intValue) // 转为IntStream避免装箱
.sum();
// 性能陷阱2:不必要的排序
List<Integer> result = numbers.stream()
.sorted() // 不必要的排序开销
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// 优化:先过滤再排序
List<Integer> optimized = numbers.stream()
.filter(n -> n % 2 == 0)
.sorted() // 数据量减少后再排序
.collect(Collectors.toList());
// 性能陷阱3:重复创建Stream
for (int i = 0; i < 10; i++) {
long count = numbers.stream() // 每次循环都创建新Stream
.filter(n -> n % i == 0)
.count();
}
// 优化:重用Stream操作
LongUnaryOperator counter = divisor -> numbers.stream()
.filter(n -> n % divisor == 0)
.count();
for (int i = 1; i < 10; i++) {
long count = counter.applyAsLong(i);
}
}
// 并行Stream的正确使用
public static void parallelStreamBestPractices() {
List<Integer> numbers = IntStream.rangeClosed(1, 10000)
.boxed()
.collect(Collectors.toList());
// 合适使用并行Stream的情况
long parallelTime = measureTime(() ->
numbers.parallelStream()
.filter(n -> isPrime(n)) // 计算密集操作
.count()
);
// 不合适使用并行Stream的情况
long sequentialTime = measureTime(() ->
numbers.stream()
.filter(n -> n < 100) // 简单操作,并行开销大
.count()
);
System.out.println("并行时间: " + parallelTime + "ms");
System.out.println("顺序时间: " + sequentialTime + "ms");
}
private static boolean isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) return false;
}
return true;
}
private static long measureTime(Runnable task) {
long start = System.currentTimeMillis();
task.run();
return System.currentTimeMillis() - start;
}
}
函数式编程的最佳实践
原则1:不变性
java
// 不可变类示例
public final class ImmutablePerson {
private final String name;
private final int age;
private final List<String> hobbies;
public ImmutablePerson(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
this.hobbies = Collections.unmodifiableList(new ArrayList<>(hobbies));
}
public String getName() { return name; }
public int getAge() { return age; }
public List<String> getHobbies() { return hobbies; }
// 使用with模式创建新对象
public ImmutablePerson withName(String newName) {
return new ImmutablePerson(newName, age, hobbies);
}
public ImmutablePerson withAge(int newAge) {
return new ImmutablePerson(name, newAge, hobbies);
}
}
原则2:纯函数
java
public class PureFunctions {
// 纯函数:相同输入总是产生相同输出,无副作用
public static int add(int a, int b) {
return a + b;
}
// 非纯函数:有副作用(修改外部状态)
private static int counter = 0;
public static int increment() {
return ++counter; // 有副作用
}
// 非纯函数:依赖外部状态
public static int getCurrentTime() {
return (int) System.currentTimeMillis(); // 结果随时间变化
}
// 纯函数式操作列表
public static List<Integer> squareList(List<Integer> numbers) {
return numbers.stream()
.map(n -> n * n) // 纯函数操作
.collect(Collectors.toList());
}
}
原则3:函数组合
java
public class FunctionComposition {
// 基础函数
public static Function<Integer, Integer> add = x -> x + 1;
public static Function<Integer, Integer> multiply = x -> x * 2;
public static Function<Integer, Integer> square = x -> x * x;
// 手动组合
public static Function<Integer, Integer> addThenMultiply = x -> multiply.apply(add.apply(x));
// 使用andThen/compose组合
public static Function<Integer, Integer> composed1 = add.andThen(multiply).andThen(square);
public static Function<Integer, Integer> composed2 = square.compose(multiply).compose(add);
// 创建通用组合器
public static <T> Function<T, T> composeAll(List<Function<T, T>> functions) {
return functions.stream()
.reduce(Function.identity(), Function::andThen);
}
// 实际应用:数据处理管道
public static void dataProcessingPipeline() {
List<Function<String, String>> textProcessors = Arrays.asList(
String::trim,
s -> s.replaceAll("\s+", " "),
String::toLowerCase,
s -> s.replaceAll("[^a-z ]", "")
);
Function<String, String> textPipeline = composeAll(textProcessors);
String result = textPipeline.apply(" HELLO WORLD!! ");
System.out.println(result); // 输出: hello world
}
}
总结与进阶学习
函数式编程的优势
- 代码简洁:减少模板代码,提高表达力
- 易于并行:不变性和纯函数天然适合并行处理
- 可测试性:纯函数更容易测试
- 组合性:函数可以像乐高积木一样组合
常见陷阱与解决方案
java
public class CommonPitfalls {
// 陷阱1:在Lambda中修改外部变量
public void pitfall1() {
int count = 0;
List<String> items = Arrays.asList("A", "B", "C");
// ❌ 错误:在Lambda中修改局部变量
// items.forEach(s -> count++); // 编译错误
// ✅ 正确:使用Atomic类型或收集结果
AtomicInteger atomicCount = new AtomicInteger(0);
items.forEach(s -> atomicCount.incrementAndGet());
long correctCount = items.stream().count();
}
// 陷阱2:过度使用Stream
public void pitfall2() {
List<String> list = Arrays.asList("A", "B", "C");
// ❌ 过度使用Stream(简单操作)
String result1 = list.stream()
.filter(s -> s.equals("B"))
.findFirst()
.orElse("Not found");
// ✅ 传统方式更简洁
String result2 = list.contains("B") ? "B" : "Not found";
// 原则:Stream适用于复杂的数据处理流水线
}
// 陷阱3:忽略空Optional
public void pitfall3() {
Optional<String> optional = Optional.ofNullable(null);
// ❌ 错误:直接调用get()
// String value = optional.get(); // 可能抛出NoSuchElementException
// ✅ 正确:提供默认值或处理空情况
String value1 = optional.orElse("default");
String value2 = optional.orElseGet(() -> generateDefault());
optional.ifPresent(v -> System.out.println(v));
}
private String generateDefault() {
return "generated default";
}
}