P45 函数式编程

news/2024/11/19 18:32:07/

P45 函数式编程

  • 1.Lambda的延迟执行
  • 2.使用 Lambda 作为参数和返回值

系统:Win10
Java:1.8.0_333
IDEA:2020.3.4

在兼顾面向对象特性的基础上,Java 语言通过 Lambda 表达式与方法引用等,为开发者打开了函数式编程的大门。下面我们做一个初探

1.Lambda的延迟执行

有些场景的代码执行后,结果不一定会被使用,从而造成性能浪费。而 Lambda 表达式是延迟执行的,这正好可以 作为解决方案,提升性能
性能浪费的日志案例

备注:日志可以帮助我们快速的定位问题,记录程序运行过程中的情况,以便项目的监控和优化

一种典型的场景就是对参数进行有条件使用,例如对日志消息进行拼接后,在满足条件的情况下进行打印输出

public class Demo01 {public static void log(int level, String msg){if (level == 1){System.out.println(msg);}}public static void main(String[] args) {String msgA = "Hello";String msgB = "World";String msgC = "Java";log(1,msgA + msgB + msgC);}
}

这段代码存在问题:无论级别是否满足要求,作为 log 方法的第二个参数,三个字符串一定会首先被拼接并传入方法内,然后才会进行级别判断。如果级别不符合要求,那么字符串的拼接操作就白做了,存在性能浪费

备注:SLF4J 是应用非常广泛的日志框架,它在记录日志时为了解决这种性能浪费的问题,并不推荐首先进行字符串的拼接,而是将字符串的若干部分作为可变参数传入方法中,仅在日志级别满足要求的情况下才会进 行字符串拼接。例如: LOGGER.debug(“变量{}的取值为{}。”, “os”, “macOS”) ,其中的大括号 {} 为占位符。如果满足日志级别要求,则会将“os”和“macOS”两个字符串依次拼接到大括号的位置;否则不会进行字 符串拼接。这也是一种可行解决方案,但 Lambda 可以做到更好

体验Lambda的更优写法
使用 Lambda 必然需要一个函数式接口

@FunctionalInterface
public interface MessageBuilder {String buildMessage();
}

然后对 log 方法进行改造

public class Demo02 {public static void log(int level, MessageBuilder mb){if (level == 1){System.out.println(mb.buildMessage());}}public static void main(String[] args) {String msgA = "Hello";String msgB = "World";String msgC = "Java";log(1,()->msgA + msgB + msgC);}
}

这样一来,只有当级别满足要求的时候,才会进行三个字符串的拼接;否则三个字符串将不会进行拼接
证明 Lambda 的延迟
下面的代码可以通过结果进行验证

public class Demo03 {public static void log(int level, MessageBuilder mb) {if (level == 1) {System.out.println(mb.buildMessage());}}public static void main(String[] args) {String msgA = "Hello";String msgB = "World";String msgC = "Java";log(2, () -> {System.out.println("Lambda执行!");return msgA + msgB + msgC;});}
}

从结果中可以看出,在不符合级别要求的情况下,Lambda 将不会执行。从而达到节省性能的效果

扩展:实际上使用内部类也可以达到同样的效果,只是将代码操作延迟到了另外一个对象当中通过调用方法 来完成。而是否调用其所在方法是在条件判断之后才执行的

2.使用 Lambda 作为参数和返回值

如果抛开实现原理不说,Java 中的 Lambda 表达式可以被当作是匿名内部类的替代品。如果方法的参数是一个函数式接口类型,那么就可以使用 Lambda 表达式进行替代。使用 Lambda 表达式作为方法参数,其实就是使用函数式 接口作为方法参数
例如 java.lang.Runnable 接口就是一个函数式接口,假设有一个 startThread 方法使用该接口作为参数,那么就可以使用 Lambda 进行传参。这种情况其实和 Thread 类的构造方法参数为 Runnable 没有本质区别

public class Demo04 {private static void startThread(Runnable task){new Thread(task).start();}public static void main(String[] args) {startThread(()-> System.out.println("线程任务开始执行!"));}
}

类似地,如果一个方法的返回值类型是一个函数式接口,那么就可以直接返回一个 Lambda 表达式。当需要通过一个方法来获取一个 java.util.Comparator 接口类型的对象作为排序器时,就可以调该方法获取

public class Demo5 {private static Comparator<String> compare() {return (a, b) -> b.length() - a.length();}public static void main(String[] args) {String[] arr = {"abc", "ab", "abcd"};System.out.println(Arrays.toString(arr));Arrays.sort(arr, compare());System.out.println(Arrays.toString(arr));}
}

其中直接 return 一个 Lambda 表达式即可


http://www.ppmy.cn/news/127791.html

相关文章

JavaScript 学习笔记 p45 - 50

对一个数进行开方&#xff1a; var result Math.sqrt(); console.time ("test");for (var i2; i<100; i) {var flag true;for (var j2; j<Math.sqrt(i); j) {if (i%j 0) {//如果进入判断则证明 i 不是质数&#xff0c;修改 flag 值为 falseflag false;//不…

P42-P45 认识函数

1. 函数的定义 函数是组织好的可以重复使用的代码段。函数可以提高应用的模块性和代码的重复使用率。 函数的参数(形式参数)可以支持多个。 def mufun1(name,times):for i in range(times):print(fI love {name}) mufun1(python,5) 2. 函数的返回值 函数的返回值&#xff0c;…

谷粒商城-基础篇-商品服务1-三级分类(P45-P58)

谷粒商城-基础篇2 一、商品服务-API-三级分类1、三级分类2、查出所有分类以及子分类2、配置网关路由与路径重写3、网关统一配置跨域4、查询-树形展示三级分类数据5、删除6、新增7、修改8、修改拖拽效果9、批量删除 商品服务-三级分类 一、商品服务-API-三级分类 1、三级分类 …

CSS基础(P45-P65)

一、基础认知 1.1CSS介绍 CSS&#xff1a;层叠式样表&#xff08;Cascading style sheets&#xff09;&#xff0c;用来给页面中的HTML标签设置样式 常见属性&#xff1a;color颜色、font-size字体大小、background-color背景颜色、width宽度、height高度 注意点&#xff1…

Day07 狂神说Java-MySQL>P40-P45

P40 Statement对象详解 executeUpdate和executeQuery 提取工具类 package com.hu.lesson02.utils;import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties;public class JdbcUtils {private static String driver null;…

寨板p45黑苹果10.12.6

这不是一个教程哈&#xff0c;只是只是一些记录吧。教程的话后续会写哈&#xff0c;有兴趣的朋友可以关注一下。前段时间喜欢上折腾黑苹果了&#xff0c;花费一些时间确实成功给几台电脑装上了黑苹果&#xff0c;其中最老的就是这台台式机了&#xff0c;机子配置没有鲁大师截图…

谷粒商城P45-P58

文章目录 分布式基础篇csdn机制问题导致图片丢失,可以查看本人的个人博客:[谷粒商城-P45-P58](https://www.r2coding.vip/articles/2022/05/04/1651673906725.html)1. 三级分类1.1 sql脚本1.2 查出所有分类以及子分类1.2.1 后段代码编写1.2.2前端代码编写1.2.2.1配置网关路由…

x38和x48是服务器芯片吗,P45和P35区别是什么?

你不组CF的话,超频方面没什么太大区别,x38和x48的区别是x38支持ddr31600和fsb1600,p35和p45的区别是p45支持pcie 2.0.其实,p35完全够用,不建议你升级成p45或者x48之类的,当然,你要组cf的话列外。。。 2007年,在支持FSB 1333MHz的英特尔X38主板还没有正式上市之际,一些主板大厂…