关于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 ...
随机推荐
- 免费ASP空间
free免费asp空间的申请方法: free免费asp空间的ftp使用方法: sise.host3v.vip/1
- Vue ref属性
ref属性 1.被用来给元素或子组件注册引用信息(id的替代者) 2.应用在html标签上获取的是真实DOM元素: 应用在组件标签上是组件实例对象 vc 3.使用方法: (1)打标识:<h1 r ...
- the default discovery settings are unsuitable for production use at least one of...的解决办法
解决办法 elasticsearch.yml加上 discovery.type: single-node
- Pyodide 中实现网络请求的 3 种方法
原文:https://lwebapp.com/zh/post/pyodide-fetch 需求 小编之前提过一个在线 Python 工具,核心技术是用到了一个叫 Pyodide 的库,能够让 Pyth ...
- MS14-064/CVE-2014-6332漏洞复现(OLE远程代码执行漏洞、IE浏览器漏洞)
漏洞介绍:MS14-064 Microsoft Internet Explorer Windows OLE Automation Array Remote Code Execution,主要利用IE浏 ...
- 【27期】Dubbo面试八连问,这些你都能答上来吗?
1.Dubbo是什么? Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目.致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA ...
- Windows 11 调整工具 TweakNow WinSecret for Windows 11 3.2.0 中文汉化版
Windows 11 调整工具 TweakNow WinSecret for Windows 11 中文版由大眼仔旭(www.dayanzai.me)发布.适用于 Windows 11 的 Tweak ...
- Springboot+Vue实现短信与邮箱验证码登录
体验网址:http://mxyit.com 示例 1.新增依赖 <!-- 短信服务 --> <dependency> <groupId>com.aliyun< ...
- 安装kvm后,在windows主机启动virt-manger后报错(no polkit agent available to authenticate action org.libvirt.unix.manage)
解决方法如下: 1. 增加libvirtd用户组 groupadd libvirtd 2.在你使用的普通用户界面执行 sudo usermod -a -G libvirtd $USER 3.设置启动 ...
- CentOS 7安装配置vsftp并搭建FTP(一)
vsftp-VSFTP是一个基于GPL发布的类Unix系统上使用的FTP服务器软件.关于这个软件的详细信息 大家可以自行百度. 以上自己安装vsftp系统环境 二.查看自己的服务器是否安装了vsftp ...