当前位置:首页>java>函数式编程

函数式编程

  • 2026-08-27 23:19:17
函数式编程

Lambda 表达式

Lambda表达式是Java 8引入的一个重要特性,它提供了一种简洁的方式来表示匿名函数。

Lambda表达式的语法

Lambda表达式的基本语法是:(parameters) -> expression 或 (parameters) -> { statements; }

语法形式示例说明
无参数() -> System.out.println("Hello")无参数的Lambda表达式
单个参数x -> x + 1单个参数可省略括号
多个参数(x, y) -> x + y多个参数需要用括号
有类型声明(int x, int y) -> x + y带类型声明的参数
多条语句(x, y) -> { int sum = x + y; return sum; }多条语句需要用花括号

Lambda表达式示例

public class LambdaExample {    public static void basicLambdaExamples() {        // 无参Lambda        Runnable runnable = () -> System.out.println("Hello from Lambda!");        runnable.run();        // 单参Lambda        Function<String, Integer> stringToInt = s -> s.length();        System.out.println("Length: " + stringToInt.apply("Hello"));        // 多参Lambda        BinaryOperator<Integer> add = (x, y) -> x + y;        System.out.println("Sum: " + add.apply(5, 3));        // 带类型声明的Lambda        BinaryOperator<Integer> multiply = (Integer x, Integer y) -> x * y;        System.out.println("Product: " + multiply.apply(4, 6));        // 多语句Lambda        Function<Integer, String> processNumber = (Integer num) -> {            if (num > 0) {                return "Positive: " + num;            } else if (num < 0) {                return "Negative: " + num;            } else {                return "Zero";            }        };        System.out.println(processNumber.apply(-5));    }    // Lambda与集合操作    public static void lambdaWithCollections() {        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");        // 使用Lambda表达式遍历集合        names.forEach(name -> System.out.println(name));        // 使用方法引用(Method Reference)        names.forEach(System.out::println);        // 使用Lambda过滤        names.stream()             .filter(name -> name.startsWith("A"))             .forEach(System.out::println);    }}

Stream API

Stream API是Java 8引入的另一个重要特性,提供了函数式编程的能力,可以对集合进行各种操作。

Stream操作类型

操作类型说明示例
中间操作返回Stream,可以链式调用filter, map, sorted, distinct
终端操作返回结果或副作用,结束Streamcollect, forEach, reduce, count

Stream常用方法

方法说明示例
filter(Predicate<T>)过滤元素stream.filter(x -> x > 5)
map(Function<T,R>)转换元素stream.map(String::length)
flatMap(Function<T,Stream<R>>)扁平化映射stream.flatMap(list -> list.stream())
distinct()去重stream.distinct()
sorted()排序stream.sorted()
limit(long n)限制元素数量stream.limit(5)
skip(long n)跳过元素stream.skip(2)
forEach(Consumer<T>)遍历stream.forEach(System.out::println)
collect(Collectors)收集结果stream.collect(Collectors.toList())
reduce(BinaryOperator<T>)归约操作stream.reduce(Integer::sum)
count()计数stream.count()
findFirst()获取第一个元素stream.findFirst()
anyMatch(Predicate<T>)是否任意匹配stream.anyMatch(x -> x > 10)
allMatch(Predicate<T>)是否全部匹配stream.allMatch(x -> x > 0)
noneMatch(Predicate<T>)是否都不匹配stream.noneMatch(x -> x < 0)

Stream API 示例

public static void basicStreamOperations() {    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);    // 过滤偶数并求平方    List<Integer> evenSquares = numbers.stream()        .filter(n -> n % 2 == 0)  // 过滤偶数        .map(n -> n * n)          // 求平方        .collect(Collectors.toList());  // 收集结果    System.out.println("Even squares: " + evenSquares);    // 字符串操作示例    List<String> words = Arrays.asList("hello", "world", "java", "stream", "api");    List<String> upperWords = words.stream()        .filter(word -> word.length() > 4)  // 过滤长度大于4的单词        .map(String::toUpperCase)           // 转大写        .sorted()                           // 排序        .collect(Collectors.toList());    System.out.println("Filtered and transformed words: " + upperWords);    // 数字流操作    int sum = IntStream.rangeClosed(1, 100)        .filter(n -> n % 2 == 0)  // 偶数        .sum();                   // 求和    System.out.println("Sum of even numbers 1-100: " + sum);}public static void advancedStreamOperations() {    List<Person> people = Arrays.asList(        new Person("Alice", 25, "Engineer"),        new Person("Bob", 30, "Designer"),        new Person("Charlie", 35, "Engineer"),        new Person("David", 28, "Manager"),        new Person("Eve", 32, "Engineer")    );    // 按职业分组    Map<String, List<Person>> groupedByJob = people.stream()        .collect(Collectors.groupingBy(Person::getJob));    System.out.println("Grouped by job: " + groupedByJob);    // 按年龄统计    IntSummaryStatistics ageStats = people.stream()        .mapToInt(Person::getAge)        .summaryStatistics();    System.out.println("Age statistics: " + ageStats);    // 查找特定条件的元素    Optional<Person> engineer = people.stream()        .filter(p -> p.getJob().equals("Engineer"))        .findFirst();    engineer.ifPresent(p -> System.out.println("First engineer: " + p.getName()));    // 字符串连接    String names = people.stream()        .map(Person::getName)        .collect(Collectors.joining(", "));    System.out.println("Names joined: " + names);}// 并行流示例public static void parallelStreamExample() {    List<Integer> numbers = IntStream.rangeClosed(1, 1000000)        .boxed()        .collect(Collectors.toList());    // 串行流    long startTime = System.currentTimeMillis();    long serialSum = numbers.stream()        .mapToLong(Long::valueOf)        .sum();    long serialTime = System.currentTimeMillis() - startTime;    // 并行流    startTime = System.currentTimeMillis();    long parallelSum = numbers.parallelStream()        .mapToLong(Long::valueOf)        .sum();    long parallelTime = System.currentTimeMillis() - startTime;    System.out.println("Serial sum: " + serialSum + ", time: " + serialTime + "ms");    System.out.println("Parallel sum: " + parallelSum + ", time: " + parallelTime + "ms");}// 内部类用于示例static class Person {    private String name;    private int age;    private String job;    public Person(String name, int age, String job) {        this.name = name;        this.age = age;        this.job = job;    }    // getter方法    public String getName() { return name; }    public int getAge() { return age; }    public String getJob() { return job; }    @Override    public String toString() {        return String.format("Person{name='%s', age=%d, job='%s'}", name, age, job);   	 }	}}

Optional 类

Optional是Java 8引入的容器类,用于解决空指针异常问题。

Optional常用方法

方法说明示例
Optional.empty()创建空OptionalOptional<String> opt = Optional.empty();
Optional.of(value)创建非空OptionalOptional<String> opt = Optional.of("Hello");
Optional.ofNullable(value)创建可能为空的OptionalOptional<String> opt = Optional.ofNullable(str);
isPresent()检查是否有值opt.isPresent()
isEmpty()检查是否为空opt.isEmpty() (Java 11+)
get()获取值(不安全)opt.get()
orElse(defaultValue)获取值或默认值opt.orElse("Default")
orElseGet(Supplier)惰性获取默认值opt.orElseGet(() -> computeDefault())
orElseThrow()无值时抛异常opt.orElseThrow()
orElseThrow(Supplier)无值时抛指定异常opt.orElseThrow(() -> new CustomException())
ifPresent(Consumer)有值时执行opt.ifPresent(System.out::println)
ifPresentOrElse(Consumer, Runnable)有值/无值分别处理opt.ifPresentOrElse(...) (Java 9+)
filter(Predicate)过滤opt.filter(s -> s.length() > 5)
map(Function)转换opt.map(String::length)
flatMap(Function)扁平化转换opt.flatMap(this::processString)

Optional示例

public class OptionalExample {    public static void basicOptionalOperations() {        // 创建Optional的不同方式        Optional<String> emptyOpt = Optional.empty();        Optional<String> nonEmptyOpt = Optional.of("Hello");        Optional<String> nullableOpt = Optional.ofNullable(null);        // 检查值是否存在        System.out.println("Empty opt present: " + emptyOpt.isPresent());        System.out.println("Non-empty opt present: " + nonEmptyOpt.isPresent());        // 获取值或默认值        String value1 = emptyOpt.orElse("Default Value");        String value2 = nonEmptyOpt.orElse("Default Value");        System.out.println("Value from empty opt: " + value1);        System.out.println("Value from non-empty opt: " + value2);        // 使用ifPresent处理值        nonEmptyOpt.ifPresent(s -> System.out.println("Got value: " + s));        // 使用map转换值        Optional<Integer> lengthOpt = nonEmptyOpt.map(String::length);        lengthOpt.ifPresent(len -> System.out.println("Length: " + len));        // 使用filter过滤        Optional<String> filteredOpt = nonEmptyOpt            .filter(s -> s.length() > 10)            .map(String::toUpperCase);        System.out.println("Filtered result: " + filteredOpt.orElse("Not found"));    }    // Optional在实际业务中的应用    public static void practicalOptionalUsage() {        UserService userService = new UserService();        // 传统方式(容易出现NPE)        User user1 = userService.findById(1L);        if (user1 != null) {            Profile profile = user1.getProfile();            if (profile != null) {                Address address = profile.getAddress();                if (address != null) {                    System.out.println("Address: " + address.getCity());                }            }        }        // 使用Optional的优雅方式        Optional.ofNullable(userService.findById(1L))            .map(User::getProfile)            .map(Profile::getAddress)            .map(Address::getCity)            .ifPresent(city -> System.out.println("Address: " + city));        // 处理可能的异常情况        String result = Optional.ofNullable(userService.findById(999L))            .map(User::getProfile)            .map(Profile::getEmail)            .orElse("No email found");        System.out.println("Email result: " + result);    }    // 内部类用于示例    static class UserService {        public User findById(Long id) {            if (id == 1L) {                return new User("John Doe", new Profile("john@example.com", new Address("New York")));            }            return null;        }    }    static class User {        private String name;        private Profile profile;        public User(String name, Profile profile) {            this.name = name;            this.profile = profile;        }        public Profile getProfile() { return profile; }    }    static class Profile {        private String email;        private Address address;        public Profile(String email, Address address) {            this.email = email;            this.address = address;        }        public String getEmail() { return email; }        public Address getAddress() { return address; }    }    static class Address {        private String city;        public Address(String city) {            this.city = city;        }        public String getCity() { return city; }    }}

函数式接口

函数式接口是只有一个抽象方法的接口,可以被Lambda表达式实现。

常用函数式接口

接口抽象方法用途示例
Predicate<T>boolean test(T t)断言,返回booleanx -> x > 5
Function<T,R>R apply(T t)转换,接收T返回Rx -> x * 2
Consumer<T>void accept(T t)消费,接收T不返回x -> System.out.println(x)
Supplier<T>T get()供应,不接收返回T() -> new Object()
UnaryOperator<T>T apply(T t)一元操作,T->Tx -> x.toUpperCase()
BinaryOperator<T>T apply(T t1, T t2)二元操作,(T,T)->T(x, y) -> x + y
BiFunction<T,U,R>R apply(T t, U u)二元函数,(T,U)->R(x, y) -> x + y
BiConsumer<T,U>void accept(T t, U u)二元消费,(T,U)(x, y) -> System.out.println(x + y)

自定义函数式接口

@FunctionalInterfacepublic interface Calculator {    int calculate(int a, int b);// 可以有默认方法default void printResult(int result) {    System.out.println("Result: " + result);}// 可以有静态方法static Calculator getAdditionCalculator() {    return (a, b) -> a + b;	}}  public class FunctionalInterfaceExample {    public static void demonstrateCustomFunctionalInterface() {        Calculator addition = (a, b) -> a + b;        Calculator multiplication = (a, b) -> a * b;       int addResult = addition.calculate(5, 3);    int multResult = multiplication.calculate(5, 3);    addition.printResult(addResult);    multiplication.printResult(multResult);    Calculator defaultCalc = Calculator.getAdditionCalculator();    defaultCalc.printResult(defaultCalc.calculate(10, 20));	}}

最新文章

随机文章