Java的函数式编程详解

 更新时间:2023年10月24日 08:20:46   作者:在下uptown  
用了这么久的Java8,我寻思这种话也好意思说出来吗,难道自己是PythonBoy出身就是看不懂Java的理由吗,身为一个合格的后端Boy不会还有人看不明白Java的函数式编程吧,接下来小编和大家浅聊一下Java的函数式编程,需要的朋友可以参考下

前言

虽然Jdk版本已经出到了20+,甚至IDEA创建maven默认项目Jdk版本都11了,但是你发任你发,我用Java8,最近别的组的同事要对接个需求,把代码仓库开给他之后反馈看不太明白代码。

用了这么久的Java8,我寻思这种话也好意思说出来吗,难道自己是PythonBoy出身就是看不懂Java的理由吗,身为一个合格的后端Boy不会还有人看不明白Java的函数式编程吧。

函数式编程

那什么是函数编程呢,说白了就是可以把函数作为参数传递给其他函数,亦或者将一个函数作为返回值从另一个函数中返回。

于是Jdk根据不同的场景提供了一些核心特性和函数式接口:

Consumer<T>:接受一个输入参数 T,并在方法内部执行操作,没有返回值。

Supplier<T>:不接受任何输入参数,提供一个结果 T。

Function<T, R>:接受一个输入参数 T,执行操作并返回一个结果 R。

Predicate<T>:接受一个输入参数 T,返回一个布尔值表示是否满足条件。

UnaryOperator<T>:接受一个输入参数 T,执行操作并返回一个与输入参数类型相同的结果。

BinaryOperator<T>:接受两个相同类型的输入参数 T,执行操作并返回一个相同类型的结果。

相信大家经常在业务代码中有过这样的场景,DAO层返回了一个Optional类,如果我们只想获得其中的某一个属性应该怎么写。

我们借助一个小菜鸡老弟的代码说,这段代码写的只能说一言难尽,按照他的想法,他只想拿到age字段,其实我们只需要借助map即可满足需求。

aa.map(Studnet::getAge)
.orElseThrow(
   () -> throw new Exception("user not found")
);

这里的orElseThrow其实就是传进去的一个方法,我们可以在方法里做些别的事,比如打印下信息之类的

aa.map(Student::getAge).orElseThrow(() -> {
    System.out.println("error! error!");
    return new Exception("user not found");
});

这就是一个很简单的函数式编程例子,把函数作为参数,在另一个函数中调用。这里举一个真实的业务案例,根据高内聚低耦合的抽象思想,我们保存数据的时候做一层前置数据校验,不同的类有不同的检查字段和方法,比如Student类要检查年龄是否大于18岁。

public class Java8Test {

    public static void main(String[] args) {
        Student student1 = Student.builder().age(10).name("uptown").build();
        savePeople(student1, (Student s1) -> {
            if (s1.getAge() < 18) {
                throw new RuntimeException("18岁禁!");
            }
        });
    }

    public static <T extends People> void savePeople(T t, Consumer<T> function) {
        function.accept(t);
        // 业务TODO
    }
}

@Data
@Builder
class People {

}

@Data
@Builder
class Student extends People {
    Integer age;
    String name;
}

这样写是不是比叠加if语句优化很多。

闭包

熟练使用函数式编程的jym对这个概念肯定不陌生,闭包就是能够读取其他函数内部变量的函数,借助网上js闭包的例子。

function makeFunc() {
	var name = "Mozilla";
	function displayName() {
		console.log(name);
	}
	return displayName;
}

var myFunc = makeFunc();
myFunc(); // "Mozilla"

可以通俗的想象成,你在房间里写了一段代码包含一个函数和一些变量。当你离开房间后,函数和变量仍然存在,它们就形成了一个闭包。当你再次进入房间时,你可以使用闭包中的函数来访问和修改之前已经修改过的变量,变量仍然记录着之前的状态。

那么Java中是否有闭包特性呢,答案是严格意义上说没有。

因为仔细想一下就发现在JVM里这套逻辑显然不符合,在栈中的变量函数结束后就会被清掉,怎么会记住之前的结果。但我们可以通过匿名内部类或lambad表达式实现,lambad本质上也是匿名内部类。

public static void main(String[] args) {
    final int i = 0;
    Supplier<Integer> sup = new Supplier<>(){
        Integer get(){
            return i;
        }
    };
}

为了保证正确性和一致性,JDK在语法上规定了lambad内部访问的局部变量必须是final修饰的。因为lambda表达式本质上创建了一个闭包,捕获了外部的局部变量,并在Lambda表达式的函数体中使用这些变量。

这只是其中一点,变量修饰为final还有一些数据一致方面的问题,这里就不再赘述了。

以上就是Java的函数式编程详解的详细内容,更多关于Java函数式编程的资料请关注脚本之家其它相关文章!

相关文章

  • java实现学生信息录入界面

    java实现学生信息录入界面

    这篇文章主要为大家详细介绍了java实现学生信息录入界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 关于maven本地仓库的配置方式

    关于maven本地仓库的配置方式

    这篇文章主要介绍了关于maven本地仓库的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 5分钟搞懂java注解@Annotation的具体使用

    5分钟搞懂java注解@Annotation的具体使用

    这篇文章主要介绍了5分钟搞懂java注解@Annotation的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • java dom4j解析xml用到的几个方法

    java dom4j解析xml用到的几个方法

    这篇文章主要介绍了java dom4j解析xml用到的几个方法,有需要的朋友可以参考一下
    2013-12-12
  • SpringBoot使用自定义json解析器的使用方法

    SpringBoot使用自定义json解析器的使用方法

    本篇文章主要介绍了SpringBoot使用自定义json解析器的使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • java的三种随机数生成方式的实现方法

    java的三种随机数生成方式的实现方法

    这篇文章主要介绍了java的三种随机数生成方式的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • spring-boot中spring-boot-maven-plugin报红错误及解决

    spring-boot中spring-boot-maven-plugin报红错误及解决

    这篇文章主要介绍了spring-boot中spring-boot-maven-plugin报红错误及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • SpringBoot 自定义注解之脱敏注解详解

    SpringBoot 自定义注解之脱敏注解详解

    这篇文章主要介绍了SpringBoot 自定义注解之脱敏注解详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • MyBatis-Plus 插件扩展的实现

    MyBatis-Plus 插件扩展的实现

    MyBatis-Plus通过插件扩展机制增强功能,基于MyBatis Interceptor拦截器,包括分页插件、逻辑删除、SQL性能分析和乐观锁等,开发者可自定义插件以适应特定需求,有效地增强SQL执行过程的控制和优化,同时注意插件使用的性能影响和执行顺序
    2024-09-09
  • Java基于Rest Assured自动化测试接口详解

    Java基于Rest Assured自动化测试接口详解

    Rest Assured 是一个基于 Java 的流行的用于测试 RESTful API 的库。这篇文章主要介绍了Java如何基于Rest Assured实现自动化测试接口,需要的可以参考一下
    2023-03-03

最新评论