关于Java的惰性求值
2024-10-21 13:39:50
最近在学scala的时候,函数传参可以是传名参数,或者传值参数
1.Scala中的传名参数是什么意思?lazy关键字有什么作用?
Scala官方文档的定义是:传名参数 仅在被使用时触发实际参数的求值运算。 它们与 传值参数 正好相反。 要将一个参数变为传名参数,只需在它的类型前加上 =>。
def calculate(input: => Int) = input * 37
测试输出
def main(args: Array[String]): Unit = {
def input(): Int ={
println("Initialized")
1
}
lazy val i = input();
println("begin for loop")
for( a <- 1 to 3){
val cal = calculate(i)
println("cal:" + cal)
}
}
output:
begin for loop
Initialized
cal:37
cal:37
cal:37
可以看到Initialized
是在begin for loop
后面打印出来,而且可以看到Initialized
在三次循环调用中,只输出了一次,这是因为有缓存的,只会在第一次使用的时候进行初始化。
2.在Java中如何实现类似的功能?
其实单纯的惰性求值,是很好实现的,可以通过Java 8 中的 functional interface Supply
来传递参数。
public static Integer calculate(Supplier<Integer> s) {
return s.get() * 37;
}
public static void main(String[] args) {
Supplier<Integer> input = () -> {
System.out.println("Initialized");
return 1;
};
System.out.println("begin for loop");
for (int i = 0; i < 3; i++) {
Integer cal = calculate(input);
System.out.println("cal:" + cal);
}
}
output:
begin for loop
Initialized
cal:37
Initialized
cal:37
Initialized
cal:37
可以看到虽然实现了惰性求值,但是每次调用的时候supplier都会去计算一遍,这个时候可以用guava提供的MemoizingSupplier
。
public static Integer calculate(Supplier<Integer> s) {
return s.get() * 37;
}
public static void main(String[] args) {
//这里返回的其实是MemoizingSupplier
com.google.common.base.Supplier<Integer> input = Suppliers.memoize(() -> {
System.out.println("Initialized");
return 1;
});
System.out.println("begin for loop");
for (int i = 0; i < 3; i++) {
Integer cal = calculate(input);
System.out.println("cal:" + cal);
}
}
output:
begin for loop
Initialized
cal:37
cal:37
cal:37
通过输出可以看到,实现的效果和scala是一样的,做到了惰性求值,且有缓存,只会被执行一次。
最新文章
- Java集合类学习笔记(Set集合)
- Effective Java 阅读笔记——并发
- postfix删除队列中的邮件
- myeclipse关闭properties文件自动转义
- Cocos2d-x中播放背景音乐
- Oracle Form属性、内置子程序、触发器、系统变量简要
- 【转】android JNI
- 历届试题 剪格子 IDA*
- erlang的脚本执行---escript
- Spark集群的任务提交执行流程
- python第五十三课——time模块
- Codeforces 382 D Permutations
- Android JAR包、Library项目
- vue中使用promise
- Selenium基础知识(八)文本域处理textarea
- jquery的load()事件和ajax中load()方法的区别
- Linux 如何将一个文件夹的所有内容授权给某一个用户
- ORACLE学习文档
- Mirror--程序访问镜像数据库的超时机制
- iptable filter nat MASQUERADE snat dat
热门文章
- Vue mixin混入的介绍
- Windows 干净启动
- 【redis】配置优化及从库优先级
- lg9018题解
- Java虚拟机中 -XX:+PrintFlagsFinal与XX:+PrintCommandLineFlags 中MaxHeapSize的值不同的原因
- SAP FBL1N屏幕增强,增加自定义的列
- linux下yum安装时出现Loaded plugins: fastestmirror
- springboot集成xxl-job问题
- 靶场练习2:cloudantvirus
- Linuxt通过命令lsof或者extundelete工具恢复误删除的文件或者目录