Function函数式接口

1️⃣ 什么是 Functional 接口

定义:在 Java 中,**函数式接口(Functional Interface)**是指 只包含一个抽象方法 的接口。
这种接口可以隐式地用 Lambda 表达式方法引用 来实现。

  • 通过 @FunctionalInterface 注解可以显式声明一个接口是函数式接口(可选,但推荐)。

  • Java 8 提供了很多预定义的函数式接口在 java.util.function 包中。

注意:函数式接口可以有 默认方法静态方法,但 只能有一个抽象方法


例子:自定义函数式接口

@FunctionalInterface
interface MyFunction {
    int operate(int a, int b); // 唯一的抽象方法

    // 默认方法可以有
    default void printHello() {
        System.out.println("Hello");
    }

    // 静态方法也可以有
    static void printStatic() {
        System.out.println("Static method");
    }
}

使用 Lambda 实现:

public class TestFunctional {
    public static void main(String[] args) {
        MyFunction add = (a, b) -> a + b;
        System.out.println(add.operate(5, 3)); // 输出 8
        add.printHello(); // 输出 Hello
    }
}

2️⃣ Java 预定义函数式接口

Java 8 的 java.util.function 包提供了丰富的函数式接口,主要有:

接口描述核心方法组合方法
Function<T,R>接收 T,返回 RR apply(T t)andThen(), compose()
Consumer<T>接收 T,返回 voidvoid accept(T t)andThen()
Supplier<T>无参数,返回 TT get()
Predicate<T>接收 T,返回 booleanboolean test(T t)and(), or(), negate()
UnaryOperator<T>接收 T,返回 TT apply(T t)andThen(), compose()
BinaryOperator<T>接收两个 T,返回 TT apply(T t1, T t2)andThen()
BiFunction<T,U,R>接收 T、U,返回 RR apply(T t, U u)andThen()
BiConsumer<T,U>接收 T、U,返回 voidvoid accept(T t, U u)andThen()
BiPredicate<T,U>接收 T、U,返回 booleanboolean test(T t, U u)and(), or(), negate()

2.1 Function<T, R>

@FunctionalInterface
public interface Function<T, R> {
  • @FunctionalInterface:标记这是一个 函数式接口

    • 函数式接口的要求:只能有 一个抽象方法

    • 编译器会检查,防止你增加第二个抽象方法。

  • T:输入类型

  • R:输出类型

功能:表示一个 从 T 到 R 的映射函数,即接受一个输入,返回一个结果。

2.1.1 核心抽象方法
R apply(T t);
  • 唯一的抽象方法,也就是函数式接口的 函数方法

  • 功能:接受一个参数 t,返回一个结果 R

  • 这是你用 lambda 实现的地方。

示例

Function<String, Integer> strLength = s -> s.length();
System.out.println(strLength.apply("Hello")); // 5

 2.1.2默认方法 compose
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
}

含义:

  • compose 表示 先执行 before,再执行当前函数

  • before:类型为 Function<? super V, ? extends T>,可以把输入 V 转换为当前函数接受的类型 T。

  • 返回一个新的函数:V -> R

示例

Function<Integer, Integer> timesTwo = x -> x * 2;
Function<String, Integer> strLength = s -> s.length();

// 先获取长度,再乘2
Function<String, Integer> lengthTimesTwo = timesTwo.compose(strLength);

System.out.println(lengthTimesTwo.apply("Hello")); // 10

解释:

  1. strLength.apply("Hello") → 5

  2. timesTwo.apply(5) → 10


 2.1.3 默认方法 andThen
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

含义:

  • andThen 表示 先执行当前函数,再执行 after

  • after:类型为 Function<? super R, ? extends V>,可以把当前函数输出 R 转换为 V。

  • 返回一个新的函数:T -> V

示例

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

解释:

  1. strLength.apply("Hello") → 5

  2. intToStr.apply(5) → "Length: 5"

✅ 与 compose 相反:compose前置函数andThen后置函数


 2.1.4 静态方法 identity
static <T> Function<T, T> identity() {
    return t -> t;
}

含义:

  • 返回一个恒等函数:输入什么,输出就是什么。

  • 常用于占位函数或者不需要变换的情况。

示例

Function<String, String> identity = Function.identity();
System.out.println(identity.apply("Hello")); // Hello

总结 Function 接口设计思想
方法用途
apply(T t)核心抽象方法,函数式接口的“函数”
compose(Function<? super V, ? extends T> before)组合函数,先执行 before,再执行当前函数
andThen(Function<? super R, ? extends V> after)组合函数,先执行当前函数,再执行 after
identity()恒等函数,输入返回自身

特点:

  • Function 支持 函数组合,非常方便进行函数式链式调用。

  • 支持 lambda方法引用,是 Java 8 函数式编程的核心接口之一。

常用方法
import java.util.function.Function;

public class FunctionDemo {
    public static void main(String[] args) {
        Function<String, Integer> stringLength = s -> s.length();
        System.out.println(stringLength.apply("Hello")); // 输出 5

       // andThen:先执行当前 Function,再执行另一个 Function
       //compose:先执行传入的 Function,再执行当前 Function

        Function<Integer, Integer> multiplyBy2 = x -> x * 2;
        Function<Integer, Integer> add3 = x -> x + 3;

        Function<Integer, Integer> combined1 = multiplyBy2.andThen(add3); // (x*2)+3
        Function<Integer, Integer> combined2 = multiplyBy2.compose(add3); // (x+3)*2

        System.out.println(combined1.apply(5)); // 13
        System.out.println(combined2.apply(5)); // 16

    }
}

​​​


2.2 Consumer<T>

import java.util.function.Consumer;

public class ConsumerDemo {
    public static void main(String[] args) {
        Consumer<String> printer = s -> System.out.println(s);
        printer.accept("Hello Consumer"); // 输出 Hello Consumer

        // andThen
        Consumer<String> printer2 = s -> System.out.println(s + "!");
        printer.andThen(printer2).accept("Test"); 
        // 输出:
        // Test
        // Test!
    }
}

2.3 Supplier<T>

import java.util.function.Supplier;
import java.util.Random;

public class SupplierDemo {
    public static void main(String[] args) {
        Supplier<Integer> randomInt = () -> new Random().nextInt(100);
        System.out.println(randomInt.get()); // 随机输出 0~99
    }
}

2.4 Predicate<T>

import java.util.function.Predicate;

public class PredicateDemo {
    public static void main(String[] args) {
        Predicate<String> isEmpty = s -> s.isEmpty();
        System.out.println(isEmpty.test("")); // true
        System.out.println(isEmpty.test("abc")); // false

        // and / or / negate
        Predicate<String> startsWithA = s -> s.startsWith("A");
        Predicate<String> combined = isEmpty.or(startsWithA);
        System.out.println(combined.test("Apple")); // true
    }
}

2.5 UnaryOperator<T> & BinaryOperator<T>

import java.util.function.UnaryOperator;
import java.util.function.BinaryOperator;

public class OperatorDemo {
    public static void main(String[] args) {
        UnaryOperator<Integer> square = x -> x * x;
        System.out.println(square.apply(5)); // 25

        BinaryOperator<Integer> sum = (a, b) -> a + b;
        System.out.println(sum.apply(3, 7)); // 10
    }
}

3️⃣ 总结

  1. 函数式接口只允许有一个抽象方法,可以有默认方法和静态方法。

  2. Lambda 表达式和方法引用可以直接实现函数式接口。

  3. Java 提供丰富的 预定义函数式接口,方便处理常见的函数式场景:

    • Function<T,R>:转换/映射

    • Consumer<T>:消费

    • Supplier<T>:提供值

    • Predicate<T>:判断条件

    • UnaryOperator<T>:一元操作

    • BinaryOperator<T>:二元操作

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值