← 返回首页
λ

Java Lambda表达式详解:函数式编程入门

📂 java ⏱ 4 min 752 words

Java Lambda表达式详解:函数式编程入门

概述

Lambda表达式是Java 8引入的特性,它提供了一种简洁的方式来表示匿名函数。Lambda表达式支持函数式编程风格,使代码更简洁、更易读。

1. Lambda表达式基础

语法

// 基本语法
(参数列表) -> { 方法体 }

// 单参数可省略括号
参数 -> { 方法体 }

// 单语句可省略大括号和return
(参数) -> 表达式

示例

import java.util.Arrays;
import java.util.List;
import java.util.function.*;

public class LambdaBasicExample {
    public static void main(String[] args) {
        // 1. 无参数Lambda
        Runnable runnable = () -> System.out.println("Hello Lambda!");
        runnable.run();
        
        // 2. 单参数Lambda
        Consumer<String> printer = s -> System.out.println(s);
        printer.accept("Hello Consumer!");
        
        // 3. 多参数Lambda
        BinaryOperator<Integer> add = (a, b) -> a + b;
        System.out.println("Add: " + add.apply(5, 3));
        
        // 4. 多行Lambda
        Function<String, Integer> stringLength = s -> {
            int length = s.length();
            System.out.println("计算长度");
            return length;
        };
        System.out.println("Length: " + stringLength.apply("Hello"));
    }
}

2. 函数式接口

import java.util.function.*;

public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        // Predicate<T>:断言,返回boolean
        Predicate<Integer> isEven = n -> n % 2 == 0;
        System.out.println("4是偶数: " + isEven.test(4));
        System.out.println("5是偶数: " + isEven.test(5));
        
        // Function<T, R>:转换
        Function<String, Integer> toLength = String::length;
        System.out.println("Hello长度: " + toLength.apply("Hello"));
        
        // Consumer<T>:消费
        Consumer<String> shout = s -> System.out.println(s.toUpperCase());
        shout.accept("hello world");
        
        // Supplier<T>:提供
        Supplier<Double> randomValue = Math::random;
        System.out.println("随机数: " + randomValue.get());
        
        // UnaryOperator<T>:一元操作
        UnaryOperator<String> exclaim = s -> s + "!";
        System.out.println(exclaim.apply("Hello"));
        
        // BinaryOperator<T>:二元操作
        BinaryOperator<Integer> multiply = (a, b) -> a * b;
        System.out.println("3 * 4 = " + multiply.apply(3, 4));
    }
}

3. 方法引用

import java.util.Arrays;
import java.util.List;
import java.util.function.*;

public class MethodReferenceExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Charlie", "Alice", "Bob", "David");
        
        // 1. 静态方法引用:ClassName::staticMethod
        names.forEach(System.out::println);
        
        // 2. 实例方法引用:instance::method
        String str = "Hello World";
        Function<String, String> toUpperCase = str::toUpperCase;
        System.out.println(toUpperCase.apply("hello"));
        
        // 3. 对象方法引用:ClassName::method
        Function<String, Integer> length = String::length;
        System.out.println("Hello长度: " + length.apply("Hello"));
        
        // 4. 构造方法引用:ClassName::new
        Supplier<List<String>> listFactory = ArrayList::new;
        List<String> newList = listFactory.get();
        System.out.println("新列表: " + newList);
        
        // 排序示例
        names.sort(String::compareToIgnoreCase);
        System.out.println("排序后: " + names);
    }
}

4. Lambda与集合操作

import java.util.*;
import java.util.stream.*;

public class LambdaWithCollections {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Charlie", "Alice", "Bob", "David", "Eve");
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // forEach
        System.out.print("Names: ");
        names.forEach(name -> System.out.print(name + " "));
        System.out.println();
        
        // filter
        List<String> filtered = names.stream()
            .filter(name -> name.length() > 3)
            .collect(Collectors.toList());
        System.out.println("Length > 3: " + filtered);
        
        // map
        List<Integer> lengths = names.stream()
            .map(String::length)
            .collect(Collectors.toList());
        System.out.println("Lengths: " + lengths);
        
        // sorted
        List<String> sorted = names.stream()
            .sorted()
            .collect(Collectors.toList());
        System.out.println("Sorted: " + sorted);
        
        // reduce
        int sum = numbers.stream()
            .reduce(0, Integer::sum);
        System.out.println("Sum: " + sum);
        
        // anyMatch
        boolean hasEven = numbers.stream()
            .anyMatch(n -> n % 2 == 0);
        System.out.println("Has even: " + hasEven);
        
        // allMatch
        boolean allPositive = numbers.stream()
            .allMatch(n -> n > 0);
        System.out.println("All positive: " + allPositive);
        
        // collect to map
        Map<String, Integer> nameLengths = names.stream()
            .collect(Collectors.toMap(
                name -> name,
                String::length
            ));
        System.out.println("Name lengths: " + nameLengths);
    }
}

5. 高级Lambda用法

闭包

import java.util.function.*;

public class ClosureExample {
    public static Function<Integer, Integer> createAdder(int x) {
        return y -> x + y;  // x是闭包变量
    }
    
    public static void main(String[] args) {
        Function<Integer, Integer> add5 = createAdder(5);
        Function<Integer, Integer> add10 = createAdder(10);
        
        System.out.println("5 + 3 = " + add5.apply(3));
        System.out.println("10 + 3 = " + add10.apply(3));
    }
}

组合

import java.util.function.*;

public class CompositionExample {
    public static void main(String[] args) {
        Function<Integer, Integer> doubleIt = x -> x * 2;
        Function<Integer, Integer> addThree = x -> x + 3;
        
        // 组合函数
        Function<Integer, Integer> doubleThenAdd = doubleIt.andThen(addThree);
        Function<Integer, Integer> addThenDouble = doubleIt.compose(addThree);
        
        System.out.println("doubleThenAdd(5): " + doubleThenAdd.apply(5));  // 13
        System.out.println("addThenDouble(5): " + addThenDouble.apply(5));  // 16
        
        // 条件组合
        Predicate<Integer> isPositive = n -> n > 0;
        Predicate<Integer> isEven = n -> n % 2 == 0;
        
        Predicate<Integer> isPositiveAndEven = isPositive.and(isEven);
        Predicate<Integer> isPositiveOrEven = isPositive.or(isEven);
        
        System.out.println("5 is positive and even: " + isPositiveAndEven.test(5));
        System.out.println("5 is positive or even: " + isPositiveOrEven.test(5));
    }
}

6. 实际应用示例

数据处理管道

import java.util.*;
import java.util.stream.*;

public class DataProcessingPipeline {
    static class Person {
        String name;
        int age;
        String city;
        
        Person(String name, int age, String city) {
            this.name = name;
            this.age = age;
            this.city = city;
        }
        
        @Override
        public String toString() {
            return name + "(" + age + ")";
        }
    }
    
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 25, "New York"),
            new Person("Bob", 30, "London"),
            new Person("Charlie", 35, "New York"),
            new Person("David", 28, "Paris"),
            new Person("Eve", 22, "London")
        );
        
        // 数据处理管道
        List<String> result = people.stream()
            .filter(p -> p.age >= 25)           // 筛选年龄>=25
            .filter(p -> p.city.equals("New York"))  // 筛选纽约
            .map(p -> p.name)                   // 提取姓名
            .sorted()                           // 排序
            .collect(Collectors.toList());       // 收集结果
        
        System.out.println("Result: " + result);
        
        // 统计信息
        IntSummaryStatistics stats = people.stream()
            .mapToInt(p -> p.age)
            .summaryStatistics();
        
        System.out.println("Average age: " + stats.getAverage());
        System.out.println("Max age: " + stats.getMax());
        System.out.println("Min age: " + stats.getMin());
        
        // 按城市分组
        Map<String, List<Person>> byCity = people.stream()
            .collect(Collectors.groupingBy(p -> p.city));
        
        System.out.println("By city: " + byCity);
    }
}

7. 最佳实践

  1. 保持简洁:Lambda表达式应该简短易读
  2. 使用方法引用:当Lambda只是调用现有方法时
  3. 避免副作用:Lambda应该是纯函数
  4. 选择合适的函数式接口:根据需求选择Predicate、Function等
  5. 使用流操作:集合操作优先使用Stream API

总结

Lambda表达式是Java 8引入的重要特性,它支持函数式编程风格,使代码更简洁、更易读。掌握Lambda表达式的语法、函数式接口和流操作,是现代Java编程的重要技能。