Java 8 函数式接口学习总结

什么是函数式接口

java 复制代码
➢ 有且仅有一个抽象方法的接口。
➢ 被 @FunctionalInterface 注解的接口,
	接口上添加 @FunctionalInterface 注解意味着该接口只能有一个抽象方法,否则会编译报错

函数式接口更多是为Lambda表达式服务的,所以函数式接口即可以适用于Lambda使用的接口。

常用的函数式接口

java 复制代码
Java8 在 java.util.function 包下预定义了大量的函数数式接口供我们使用。其中比较常用的如:
➢ Supplier 接口,供给型接口
➢ Consumer 接口,消费型接口
➢ Predicate 接口,判断型接口
➢ Function 接口,函数型接口

➢ Supplier 接口

提供者接口,只有一个无参的方法:

  • T get() 提供指定类型的数据。

Supplier 接口应用场景:

  • 惰性计算:只有在需要时才计算或获取值,而不是立即执行。
  • 生成值:用于生成一些值,例如随机数、默认配置等。

源码:

java 复制代码
package java.util.function;

@FunctionalInterface
public interface Supplier<T> {
	
	/**
     * 提供指定类型的数据。
     */
    T get();
}

案例:

java 复制代码
// Supplier 接口,泛型参数是出参类型,不接受参数,但是会提供结果
Supplier<String> supplier = () -> "提供一个结果";
System.out.println(supplier.get());

➢ Consumer 接口

消费接口,对给定的参数进行消费,无返回结果。接口中提供2️⃣个方法:

  • void accept(T t) 将给定数据进行消费的方法。
  • Consumer andThen(Consumer<? super T> after) 将多个Consumer按顺序排列,先执行accept操作,然后执行after的accept操作。

Consumer 接口的应用场景:

  • 集合操作: 集合遍历(list.stream().forEach(Consumer<? super T> action))
  • 数据处理: 将待处理的处理进行处理,包括但不限于持久化操作等

源码:

java 复制代码
package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Consumer<T> {

    /**
     * 将给定数据进行消费的方法。
     */
    void accept(T t);

    /**
     * 将多个Consumer按顺序排列,先执行accept操作,然后执行after的accept操作。
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

案例1:

java 复制代码
Consumer<String> consumer = x -> {
    System.out.println(x);
};
consumer.accept("接受参数");

案例2:

java 复制代码
Consumer<String> first = x -> System.out.println("first:" + x);
Consumer<String> second = x -> System.out.println("second:" + x);

Consumer<String> result = first.andThen(second);

//调用了accept 后,会先执行 first 容器里的代码,再执行 second 容器里的代码
result.accept("Hello");

➢ Predicate 接口

断言接口,对给定的参数进行判断,返回断言结果。接口中提供5️⃣个方法:

  • boolean test(T t) 对给定的参数进行判断,返回一个布尔值。
  • Predicate and(Predicate<? super T> other) 返回一个逻辑的否定,对应逻辑非。
  • Predicate negate() 返回一个逻辑的否定,对应逻辑非。
  • Predicate or(Predicate<? super T> other) 返回一个组合判断,对应短路或。
  • static Predicate isEqual(Object targetRef) 返回一个断言对象,方便与给定参数进行equals对比

Predicate 接口应用:

  • 断言操作
  • 过滤操作

源码:

java 复制代码
package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Predicate<T> {

    /**
     * 对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值。
     */
    boolean test(T t);

    /**
     * 返回一个组合判断,对应短路与。
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
     * 返回一个逻辑的否定,对应逻辑非。
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    /**
     * 返回一个组合判断,对应短路或。
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /**
     * 两个参数是否相等
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

案例1:

java 复制代码
Predicate<String> predicate = x -> {
    return x == "a";
};

System.out.println(predicate.test("z"));
// false

System.out.println(predicate.test("a"));
// true

System.out.println(predicate.negate().test("a"));
// false

案例2:

java 复制代码
Predicate<String> predicate = x -> {
    return x == "a";
};

Predicate<String> predicate2 = x -> {
    return x == "z";
};

Predicate<String> and = predicate.and(predicate2);
System.out.println(and.test("z"));
// false

Predicate<String> or = predicate.or(predicate2);
System.out.println(or.test("z"));
// true

Predicate<String> a = Predicate.isEqual("a");
Predicate<String> b = Predicate.isEqual("b");
System.out.println(a.or(b).test("a"));
// true
        

➢ Function 接口

函数接口,将给定参数进行计算后按指定类型返回。接口中提供4️⃣个方法:

  1. R apply(T t) 执行计算操作的函数
  2. Function<V, R> compose(Function<? super V, ? extends T> before) 返回一个组合函数,首先将before函数应用于输入,然后将该函数应用于结果。
  3. Function<T, V> andThen(Function<? super R, ? extends V> after) 返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果。
  4. static Function<T, T> identity() 返回其输入参数的函数

Function 接口应用:

  • 应用极广,可以说放之皆准

源码:

java 复制代码
package java.util.function;

import java.util.Objects;

@FunctionalInterface
public interface Function<T, R> {

    /**
     * 函数
     */
    R apply(T t);

    /**
     * 返回一个组合函数,首先将before函数应用于输入,然后将该函数应用于结果。
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    /**
     * 返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果。
     */
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    /**
     * 返回其输入参数的函数
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

案例1:

java 复制代码
Function<String, String> function1 = x -> {
    return "null-" + x;
};

System.out.println(function1.apply("1"));
// null-1

System.out.println(function1.andThen(function1).apply("2"));
// null-null-2

案例2:

java 复制代码
Function<String, String> function1 = x -> {
    return "null-" + x;
};

Function<String, String> function2 = x -> {
    return "non-" + x;
};

System.out.println(function1.andThen(function2).apply("2"));
// non-null-2

System.out.println(function1.compose(function2).apply("2"));
// null-non-2

案例3:

java 复制代码
System.out.println(Function.identity().apply("aaaa"));
// aaaa
相关推荐
咸甜适中15 分钟前
rust语言AI编程学习笔记(五)clap命令行参数解析
学习·rust·ai编程
诗句藏于尽头24 分钟前
deepseek harness对接商汤科技免费大模型使用教程
人工智能·科技·学习
xiaohaiAIgeo36 分钟前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识
chemddd1 小时前
豆包生成 亚马逊链接的视频
学习·交友
weixin_431600441 小时前
NestJS 入门(7):生命周期钩子——构造函数和 `OnModuleInit` 差在哪?
前端·后端·学习·node.js·nest.js
小强库计算机毕业设计1 小时前
基于 Spring Boot + Vue3 的校园管理系统
java·spring boot·后端·项目实战·管理系统·技术分享·校园管理系统实战
工业HMI实战笔记1 小时前
解放双手,声控未来:抗噪语音交互如何革新嘈杂车间的HMI操作体验
人工智能·学习·自动化·制造
霸道流氓气质1 小时前
Java中信号量(Semaphore):从本地到分布式
java·开发语言·分布式
怪奇云呼军1 小时前
G.711、Opus 和重采样会拖慢识别吗?闪电智能VoiceAgent 的音频入口怎么选
java·人工智能·python·算法·云计算·音视频
编程令我快乐1 小时前
maven部分构建参数讲解
java·maven