关于Java的惰性求值
最近在学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的惰性求值的更多相关文章
- Stream01 定义、迭代、操作、惰性求值、创建流、并行流、收集器、stream运行机制
1 Stream Stream 是 Java 8 提供的一系列对可迭代元素处理的优化方案,使用 Stream 可以大大减少代码量,提高代码的可读性并且使代码更易并行. 2 迭代 2.1 需求 随机创建 ...
- C#函数式编程之惰性求值
惰性求值 在开始介绍今天要讲的知识之前,我们想要理解严格求值策略和非严格求值策略之间的区别,这样我们才能够深有体会的明白为什么需要利用这个技术.首先需要说明的是C#语言小部分采用了非严格求值策略,大部 ...
- 惰性求值——lodash源码解读
前言 lodash受欢迎的一个原因,是其优异的计算性能.而其性能能有这么突出的表现,很大部分就来源于其使用的算法--惰性求值. 本文将讲述lodash源码中,惰性求值的原理和实现. 一.惰性求值的原理 ...
- c++11实现l延迟调用(惰性求值)
惰性求值 惰性求值一般用于函数式编程语言中,在使用延迟求值的时候,表达式不在它被绑定到变量之后就立即求值,而是在后面的某个时候求值. 可以利用c++11中的std::function, lam ...
- GString惰性求值
当对一个GString实例求值时,如果其中包含一个变量,该变量的值会被简单地打印到一个Writer,通常是一个StringWriter.然而,如果GString中包含的是一个闭包,而非变量,该闭包就会 ...
- Java描述表达式求值的两种解法:双栈结构和二叉树
Java描述表达式求值的两种解法:双栈结构和二叉树 原题大意:表达式求值 求一个非负整数四则混合运算且含嵌套括号表达式的值.如: # 输入: 1+2*(6/2)-4 # 输出: 3.0 数据保证: 保 ...
- 蓝桥杯算法训练 java算法 表达式求值
问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的值. 样例输入 1-2+3*(4-5) 样例输出 - ...
- java实现表达式求值 (20 分)-------非递归版
Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近由学会了一些简单的函数求值.比如,它知道函数min(20, 23)的值是20, add(10, 98)的值是108等等.经过训练,Dr.Kong ...
- [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)
Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
随机推荐
- 第三章-标准SQL语句
3.1 SQL概述: SQL:结构化查询语言,是关系数据库的标准语言,SQL是一个通用的.功能极强的关系数据库语言 结构化查询:理解:就是只要告诉数据库我要干什么,怎么干就可以了 3.1.2 SQL的 ...
- element-ui下表格头部字段hover显示tips信息
记录一下表格头部加hover之后显示tips信息循环,或单独的el-table-column都可以哦 <el-table-column prop="name&q ...
- MySQL突然连接失败
mysql突然连接失败问题 1.报错 MySQL error: 2013, "Lost connection to MySQL server at 'reading initial comm ...
- vue+elementUI表格实现自定义右键菜单
组件代码: <template> <div id="contextmenu" class="contextmenu open"> < ...
- python服务返回text与json
json.dumps(),loads()和jsonify()的区别 使用方法不同: dumps和loads方法,来自json模块,而json模块是python中的,可以直接导入: import jso ...
- Oracle 的merge into 语法转postgre
Oracle的merge into 语法 MERGE INTO t1 USING (SELECT id,name FROM t2) t2 ON ( t1.id=t2.id) //主键 WHEN M ...
- 统计tomcat的access日志
统计tomcat的access日志的ip次数,并按次数排序 awk '{sum[$1]++}END{for(i in sum) print i "\t" sum[i]}' loca ...
- IntelliJ IDEA2021.3破解教程【Windows10系统】
IntelliJ IDEA2021.3破解教程[Windows10系统] 以下仅为本人工作.学习过程中所接触到的内容,不足之处请多包涵. 官网下载地址 最新版:https://www.jetbrain ...
- 高校github课程资源汇总
序号 学校名称 学校类型 课程资源链接 1 清华大学 Top 计算机系课程攻略 https://github.com/Salensoft/thu-cst-cracker https://github. ...
- 081_Introducing trigger handler class
案例分析: 我们对一个Object写多个独立得Trigger. 但最终这不是最好的做法. 在Salesforce中,只为每个SObject设置一个触发器总是好的. 原因:每个独立触发器的执行顺序始终未 ...