一文教会你JDK8的函数式编程

article/2025/10/19 22:02:03

JDK8的1个新特性就是支持函数式接口(Functional Interface)。

函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

函数式接口可以被隐式转换为Lambda表达式。

我们也可以自行定义函数式接口,如:

@FunctionalInterface
interface GreetingService{void sayMessage(String message);
}

然后通过Lambda表达式来定义接口实现(JAVA8之前一般使用匿名类来实现):

public class GreetingServiceTest {public static void main(String[] args) {GreetingService greetingService = message -> {System.out.println("Hello " + message);};greetingService.sayMessage("Mary");}
}执行返回:Hello Mary

JDK8官方也为我们定义了一些常用的函数式接口,如下图所示:

在这里插入图片描述
在这里插入图片描述

接下来,我重点介绍其中比较重要的几个函数式接口。

Function<T, R>

接收1个输入参数,返回1个结果。

  • 源码
@FunctionalInterface
public interface Function<T, R> {// 将T类型转化为R类型R apply(T t);// 先执行参数传入的Function,再执行本Functiondefault <V> Function<V, R> compose(Function<? super V, ? extends T> before) {Objects.requireNonNull(before);return (V v) -> apply(before.apply(v));}// 和compose相反,先执行本Function,再执行参数传入的Functiondefault <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}// 静态方法,返回传入的泛型T自身static <T> Function<T, T> identity() {return t -> t;}
}
  • 代码示例
public class FunctionTest {public static Integer calculate(Integer i, Function<Integer, Integer> function){return function.apply(i);}public static void main(String[] args) {Function<Integer, Integer> func1 = i -> {return i+5;};Function<Integer, Integer> func2 = i -> {return i*5;};System.out.println(calculate(6, func1));System.out.println(calculate(6, func2));System.out.println(calculate(6, func1.compose(func2)));System.out.println(calculate(6, func1.andThen(func2)));System.out.println(Function.identity().apply("6+5"));}
}执行输出:11
30
35
55
6+5

Supplier

生产函数,无参数,返回1个结果。

  • 源码
@FunctionalInterface
public interface Supplier<T> {// 生产1个元素T get();
}
  • 代码示例
public class SupplierTest {public static void main(String[] args) {Supplier<String> supplier = () -> {return "商品";};System.out.println(supplier.get());}
}执行输出:商品

Consumer

消费函数,接收1个输入参数并且无返回的操作。

  • 源码
@FunctionalInterface
public interface Consumer<T> {// 消费输入tvoid accept(T t);// 先执行本接口的消费逻辑,再执行传入函数的消费逻辑default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
}
  • 代码示例
public class ConsumerTest {public static void main(String[] args) {Consumer<String> consumer1 = s -> {System.out.println(s + ",我是消费者1");};Consumer<String> consumer2 = s -> {System.out.println(s + ",我是消费者2");};consumer1.accept("铁甲小宝");System.out.println("################");consumer1.andThen(consumer2).accept("铁甲小宝");}
}执行输出:铁甲小宝,我是消费者1
################
铁甲小宝,我是消费者1
铁甲小宝,我是消费者2

Predicate

断言函数,接受1个输入参数,返回1个布尔值结果。

  • 源码
@FunctionalInterface
public interface Predicate<T> {// 对输入进行断言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);}// 取反@SuppressWarnings("unchecked")static <T> Predicate<T> not(Predicate<? super T> target) {Objects.requireNonNull(target);return (Predicate<T>)target.negate();}
}
  • 代码示例
public class PredicateTest {public static void main(String[] args) {// 断言输入值是否大于10Predicate<Integer> isSuperTen = i -> {return i>10;};System.out.println(isSuperTen.test(11));System.out.println(isSuperTen.test(6));// 取反,断言输入值是否不大于10Predicate<Integer> negate = isSuperTen.negate();System.out.println(negate.test(6));// 断言输入值是否大于20Predicate<Integer> isLowerTwenty = i -> {return i<20;};// 断言15是否>10且<20System.out.println(isSuperTen.and(isLowerTwenty).test(15));// 断言21是否>10且<20System.out.println(isSuperTen.and(isLowerTwenty).test(21));// 断言21是否>10或<20System.out.println(isSuperTen.or(isLowerTwenty).test(21));}
}执行输出:true
false
true
true
false
true

BiFunction<T, U, R>

接受1个入参T和U,并返回结果R。

  • 源码
@FunctionalInterface
public interface BiFunction<T, U, R> {// 根据输入t和u,转化为输出rR apply(T t, U u);// 先执行本函数,再执行参数传入的函数default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t, U u) -> after.apply(apply(t, u));}
}
  • 代码示例
public class BiFunctionTest {public static void main(String[] args) {BiFunction<String, Integer, String> biFunction = (key, value) -> {return (key + ":" + String.valueOf(value));};String key = "age";Integer value = 18;System.out.println(biFunction.apply(key, value));Function<String, String> afterFunction = s -> {System.out.println("执行后继函数,添加前缀***");return "***-" + s;};System.out.println(biFunction.andThen(afterFunction).apply(key, value));}
}执行输出:age:18
执行后继函数,添加前缀***
***-age:18

BiConsumer<T, U>

代表了1个接受2个输入参数的操作,并且不返回任何结果。

  • 源码
@FunctionalInterface
public interface BiConsumer<T, U> {// 消费2个输入t和uvoid accept(T t, U u);// 先执行该函数的消费逻辑,再执行传入函数的消费逻辑default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {Objects.requireNonNull(after);return (l, r) -> {accept(l, r);after.accept(l, r);};}
  • 代码示例
public class BiConsumerTest {public static void main(String[] args) {BiConsumer<String, Integer> biConsumer1 = (s, i) -> {System.out.println("我是消费逻辑1" + "," + s + "," + String.valueOf(i+10));};BiConsumer<String, Integer> biConsumer2 = (s, i) -> {System.out.println("我是消费逻辑2" + "," + s + "," + String.valueOf(i*3));};biConsumer1.accept("铁甲小宝", 6);System.out.println("###########");biConsumer1.andThen(biConsumer2).accept("铁甲小宝", 6);}
}执行输出:我是消费逻辑1,铁甲小宝,16
###########
我是消费逻辑1,铁甲小宝,16
我是消费逻辑2,铁甲小宝,18

BiPredicate<T, U>

对2个输入参数T和U进行断言,返回1个布尔值输出。

  • 源码
@FunctionalInterface
public interface BiPredicate<T, U> {// 断言输入t和uboolean test(T t, U u);// 并操作default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other) {Objects.requireNonNull(other);return (T t, U u) -> test(t, u) && other.test(t, u);}// 取反default BiPredicate<T, U> negate() {return (T t, U u) -> !test(t, u);}// 或操作default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other) {Objects.requireNonNull(other);return (T t, U u) -> test(t, u) || other.test(t, u);}
}
  • 代码示例
public class BiPredicateTest {public static void main(String[] args) {// 判断输入1是否大于10,且输入2小于20BiPredicate<String, Integer> biPredicate = (s, i) -> {return Integer.valueOf(s) > 10 && i < 20;};System.out.println(biPredicate.test("15", 16));System.out.println(biPredicate.test("15", 21));System.out.println(biPredicate.test("6", 21));}
}执行输出:true
false
false

其他函数接口基本原理类似,不再赘述。

之所以今天讲解一下JDK8的函数式编程,主要是为后续的Flink源码解析系列做一些前置知识储备,因为Flink源码里有大量的函数式接口实践。

本文到此结束,谢谢阅读!


http://chatgpt.dhexx.cn/article/MvrKb9rM.shtml

相关文章

Modern C++ 学习笔记——C++函数式编程

往期精彩&#xff1a; Modern C 学习笔记——易用性改进篇Modern C 学习笔记 —— 右值、移动篇Modern C 学习笔记 —— 智能指针篇Modern C 学习笔记 —— lambda表达式篇Modern C 学习笔记 —— C面向对象编程Modern C 学习笔记 —— C函数式编程 Modern C 学习笔记——C函数…

java8函数式编程实例

什么是函数式编程 函数式编程是java8的一大特色&#xff0c;也就是将函数作为一个参数传递给指定方法。别人传的要么是基本数据类型&#xff0c;要么就是地址引用 &#xff0c;我们要穿一个“动作”。 Stream 说到函数式编程&#xff0c;就不得不提及Stream&#xff0c;Stre…

Scala函数式编程

一、函数式编程定义&#xff1a; Scala是一门既面向对象&#xff0c;又面向过程的语言。在Scala中&#xff0c;函数与类、对象地位是一样&#xff0c;所以说scala的面向过程其实就重在针对函数的编程 了&#xff0c;所以称之为函数式编程 在Scala中定义函数需要使用 def 关键…

什么是函数式编程?

当我们说起函数式编程来说&#xff0c;我们会看到如下函数式编程的长相&#xff1a; 函数式编程的三大特性&#xff1a; immutable data 不可变数据&#xff1a;像Clojure一样&#xff0c;默认上变量是不可变的&#xff0c;如果你要改变变量&#xff0c;你需要把变量copy出去修…

python函数式编程

大家好 这里还还还是长弓 今天我们来讲讲python中的函数式编程 目录 函数式编程 高阶函数 map reduce filter sorted 返回函数 闭包 nonlocal使用 匿名函数lambda 装饰器 偏函数 函数式编程 有些同学疑惑了&#xff0c;我们已经学了函数&#xff0c;为什么还要学这…

函数式编程

Functional Programming 什么是函数式编程 函数式编程的思维方式&#xff1a;把显示世界的事务和事物之间的联系抽象到程序世界&#xff08;对运算过程进行抽象&#xff09; 函数式编程中的函数指的数学中的函数即映射关系&#xff0c;输入的值对应一个输出的值&#xff0c;…

appium环境搭建python_appium环境搭建python

1&#xff0c;appium是开源的移动端自动化测试框架&#xff1b;2&#xff0c;appium可以测试原生的、混合的、以及移动端的web项目&#xff1b;3&#xff0c;appium可以测试ios&#xff0c;android应用(当然了&#xff0c;还有firefox os)&#xff1b;4&#xff0c;appium是跨平…

Windows下Appium环境搭建小结

文章目录 Windows下Appium环境搭建小结需要安装的软件1. JDK下载安装/配置 2. Android SDK3. Maven下载安装/配置 4. Appium下载安装/配置 5. Eclipse TestNG 和 ADT 插件下载安装一条龙配置1、先配置Maven 创建一个项目 Windows下Appium环境搭建小结 本文需要读者已安装了Ec…

Mac端Python+Appium环境搭建

一、安装java sdk java安装&#xff1a;下载完直接安装jdk1.8 二、 安装Android Studio 1.下载安装 下载地址&#xff1a;https://www.androiddevtools.cn/# 2.安装完成后&#xff0c;打开SDK Manager 三、JAVA SDK和Android SDK环境变量配置 1.终端输入&#xff1a;ls…

安卓移动端appium环境搭建流程

安卓移动端appium环境搭建流程 基本步骤: 安装Node.js 安装JDK&#xff0c;及配置环境变量 安装SDK&#xff0c;及配置环境变量 安装Appium桌面版本(建议安装GitHub的最新版) python中pip下载Appium-Python-Client 下载allure-2.13.8并加入环境变量 管理员身份运行appiu…

pythonappium环境搭建_python+appium 环境搭建

最近学习了一下python语言&#xff0c;听说appium是做app的ui层的自动化的一个很好的框架&#xff0c;也是很多人在学习的框架&#xff0c;所以很感兴趣&#xff0c;也特意来学习一下&#xff0c;下面是我学习过程的一些心得和总结&#xff0c;希望对大家有所帮助。 一、环境搭…

Appium环境搭建(集齐Windows和MacOS的宝藏内容)

Appium环境搭建目录 Windows系统环境下安装Node.js安装JDK及环境变量配置添加环境变量 安装SDK添加环境变量 安装Appium可通过三种方法安装安装 **appium-doctor** MacOS系统环境下安装xcode安装依赖安装WebDriverAgent运行WebDriverAgent windows 安装 tidevice常用的tidevice…

mac appium环境搭建

appium环境的搭建其实也不复杂&#xff0c;主要是配置的比较多&#xff0c;只是在配置的过程中&#xff0c;根据当时的机器配置会遇到一些具体问题&#xff0c;一个个解决就可以了。 安装下面这篇文章搭建就可以了 超详细的Mac下appium环境搭建 配置java环境有问题&#xff0c;…

pythonappium环境搭建_python appium环境搭建

1&#xff0c;appium是开源的移动端自动化测试框架&#xff1b; 2&#xff0c;appium可以测试原生的、混合的、以及移动端的web项目&#xff1b; 3&#xff0c;appium可以测试ios&#xff0c;android应用&#xff08;当然了&#xff0c;还有firefox os&#xff09;&#xff1…

Appium 环境搭建

一、下载并安装appium客户端(勿装1.15.1版本,1.15.1版本很多坑) 进入appium官网http://appium.io/下载版本&#xff0c;将下载好的版本按照步骤进行安装 Appium-Python-Client第三方包 pip3 install Appium-Python-Client -i https://pypi.tuna.tsinghua.edu.cn/simple 二…

appium环境搭建全套

环境 1 Node.js 2 Appium 3 Appium-desktop 4 Appium-Python-Client 5 Python 6 JDK 7 Andriod SDK 8 Appium-doctor 一、安装Node.js 下载地址&#xff1a;https://nodejs.org/en/download/releases/ 注意&#xff1a;Appium版本是1.7.2&#xff0c;则选择的No…

Appium环境搭建

一、Appium框架原理 1.介绍 appium是一个移动端的自动化测试框架&#xff0c;可用于测试原生应用&#xff0c;移动网页应用和混合应用&#xff0c;支持iOS和Android。 2.原理 appium可以理解为一个c/s架构软件&#xff0c;在pc端安装的appium server端&#xff0c;通过appi…

Appium环境搭建教程

最近打算研究开发一个手机的自动化小工具&#xff0c;奈何在这方面自己是一个小白&#xff0c;于是开始针对手机进行研究。由于主要使用Appium这个工具&#xff0c;因此本文主要讲解Appium环境的搭建&#xff0c;并结合自己的实践讲一讲需要避过的坑。 一、 安装Node.js Node.…

MySQL函数语句

目录 一、MySQL数据库函数作用二、MySQL数据库函数分类1.1.1、数学函数常用的数学函数1、abs(x)&#xff1a;返回x的绝对值2、rand() &#xff1a;返回0到1的随机数3、mod(x&#xff0c; y) &#xff1a;返回x除以y以后的余数4、power(x&#xff0c; y)“&#xff1a;返回x的y次…

MySQL函数(=)

1 将username字段的截取两个字符&#xff0c;其中将包含为1的字符替换为q SELECT REPLACE(SUBSTRING(username,1,2),1,q) FROM guanliyuan; 2 将日期时间转换为字符串 SELECT DATE_FORMAT(2009-10-11 22:12:12,%Y%m%d%H%i%s); 3 从日期中截取年份 SELECT SUBSTRING(DATE_FO…