最近在学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的惰性求值的更多相关文章

  1. Stream01 定义、迭代、操作、惰性求值、创建流、并行流、收集器、stream运行机制

    1 Stream Stream 是 Java 8 提供的一系列对可迭代元素处理的优化方案,使用 Stream 可以大大减少代码量,提高代码的可读性并且使代码更易并行. 2 迭代 2.1 需求 随机创建 ...

  2. C#函数式编程之惰性求值

    惰性求值 在开始介绍今天要讲的知识之前,我们想要理解严格求值策略和非严格求值策略之间的区别,这样我们才能够深有体会的明白为什么需要利用这个技术.首先需要说明的是C#语言小部分采用了非严格求值策略,大部 ...

  3. 惰性求值——lodash源码解读

    前言 lodash受欢迎的一个原因,是其优异的计算性能.而其性能能有这么突出的表现,很大部分就来源于其使用的算法--惰性求值. 本文将讲述lodash源码中,惰性求值的原理和实现. 一.惰性求值的原理 ...

  4. c++11实现l延迟调用(惰性求值)

    惰性求值 惰性求值一般用于函数式编程语言中,在使用延迟求值的时候,表达式不在它被绑定到变量之后就立即求值,而是在后面的某个时候求值.     可以利用c++11中的std::function, lam ...

  5. GString惰性求值

    当对一个GString实例求值时,如果其中包含一个变量,该变量的值会被简单地打印到一个Writer,通常是一个StringWriter.然而,如果GString中包含的是一个闭包,而非变量,该闭包就会 ...

  6. Java描述表达式求值的两种解法:双栈结构和二叉树

    Java描述表达式求值的两种解法:双栈结构和二叉树 原题大意:表达式求值 求一个非负整数四则混合运算且含嵌套括号表达式的值.如: # 输入: 1+2*(6/2)-4 # 输出: 3.0 数据保证: 保 ...

  7. 蓝桥杯算法训练 java算法 表达式求值

    问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的值. 样例输入 1-2+3*(4-5) 样例输出 - ...

  8. java实现表达式求值 (20 分)-------非递归版

    Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近由学会了一些简单的函数求值.比如,它知道函数min(20, 23)的值是20, add(10, 98)的值是108等等.经过训练,Dr.Kong ...

  9. [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)

    Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...

  10. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

    Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...

随机推荐

  1. java如何将逗号分隔的字符串转成int或者long数组

    String str = "1,2,3";//先将他转化成int的数组如上述:欲将str 转成 数值型数组 利用 split 函数先以 ,分割 String str = " ...

  2. Java 8 在使用内存爆了以后会发生什么?hs_err_pid 日志如何看?

    问题: Java进程被终止了,然后在应用的目录中发现了hs_err_pid日志. 运维反馈,结论是内存不够了 之前一直运行没有问题,没什么新增访问量,为什么会内存溢出,进程被killer掉类? 1.第 ...

  3. C++用递归实现求解相关函数

    //递归实现Hanoi塔问题#include<iostream>#include<cstdlib>using namespace std;#define MAXSIZE 100 ...

  4. Oracle 的merge into 语法转postgre

    Oracle的merge into 语法 MERGE INTO t1 USING (SELECT id,name FROM t2) t2 ON ( t1.id=t2.id)   //主键 WHEN M ...

  5. 对APP渗透测试之抓包

    一.APP渗透测试的原理 APP(手机软件),APP测试和web测试基本没有区别,一个网站存在SQL注入,用PC端浏览器去访问存在SQL注入漏洞,用手机浏览器去访问一样也存在SQL注入漏洞. 大部分漏 ...

  6. vue跨行跨列动态表格生成

    一.思路步骤: 根据后台传输的数据进行格式转化: 索引为多少的时候进行跨行: <table id="table"> <thead> <tr> & ...

  7. TPS,RPS,QPS,RT的区别

    以下是对性能中各项指标的解释:   1.TPS:Transaction Per Second,服务器每秒处理事务数,是衡量系统性能的一个非常重要的指标.   计算公式:TPS= 总请求数 / 总时间. ...

  8. 生成数据库文档 —— Spring Boot + Screw

    1.创建一个SpringBoot项目(本人使用的是IntelliJ IDEA 2020.1 x64) 最佳简单的项目配置如下: 2.添加相关依赖 <!--screw依赖--> <de ...

  9. Ubuntu18.04LTS虚拟机优化

    1.没网 刚安装好没网,可以设置NAT连接,也可以直接设置为桥接模式联网.这里直接桥接. 网络中心使用的是以太网,所以就在菜单的"编辑"里的"虚拟网络编辑器"里 ...

  10. 【QT+MSVC2015】不安装VS2015,QT配置MSVC2015编译环境

    本文介绍不安装VS2015的情况下在QT5.10中配置MSVC2015编译器. 系统:windows系统 QT版本:5.10.1 所需文件: QT安装程序--qt-opensource-windows ...