Java Lambda表达式与函数式编程深度解析

引言: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
    }
}

总结与进阶学习

函数式编程的优势

  1. 代码简洁:减少模板代码,提高表达力
  2. 易于并行:不变性和纯函数天然适合并行处理
  3. 可测试性:纯函数更容易测试
  4. 组合性:函数可以像乐高积木一样组合

常见陷阱与解决方案

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";
    }
}
相关推荐
VX:Fegn08958 小时前
计算机毕业设计|基于springboot + vue智慧医药系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
两个蝴蝶飞13 小时前
Java量化系列(四):实现自选股票维护功能
java·经验分享
短剑重铸之日15 小时前
7天读懂MySQL|Day 5:执行引擎与SQL优化
java·数据库·sql·mysql·架构
酒九鸠玖15 小时前
Java--多线程
java
Dreamboat-L15 小时前
云服务器上部署nginx
java·服务器·nginx
长安er15 小时前
LeetCode215/347/295 堆相关理论与题目
java·数据结构·算法·leetcode·
cici1587416 小时前
C#实现三菱PLC通信
java·网络·c#
k***921617 小时前
【C++】继承和多态扩展学习
java·c++·学习
weixin_4407305017 小时前
java结构语句学习
java·开发语言·学习
JIngJaneIL17 小时前
基于java+ vue医院管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot