热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何将字符串转换为lambda表达式?-Howtoconvertastringtoalambdaexpression?

Iwasthinkingabitandcameupwithaninterestingproblem,supposewehaveaconfiguration(input

I was thinking a bit and came up with an interesting problem, suppose we have a configuration (input) file with:

我想了一下,想出了一个有趣的问题,假设我们有一个配置(输入)文件:

x -> x + 1
x -> x * 2
x -> x * x
x -> -x

And furthermore we have a list of Integers:

此外,我们有一个整数列表:

List list = new ArrayList<>();
list.addAll(Arrays.toList(1, 2, 3, 4, 5));

Is there a way to convert the Strings (x -> x + 1, etc.) to Objects that represent a lambda expression? Which could then be used as:

有没有办法将字符串(x - > x + 1等)转换为表示lambda表达式的对象?然后可以用作:

Object lambda = getLambdaFromString("x -> x + 1");
if (lambda.getClass().equals(IntFunction.class) {
    list.stream().forEach()
        .mapToInt(x -> x)
        .map(x -> ((IntFunction)lambda).applyAsInt(x))
        .forEach(System.out::println);
}

How would I write such a method getLambdaFromString?

我怎么写这样的方法getLambdaFromString?

  • Is there something I could reuse from the JDK/JRE?
  • 我可以从JDK / JRE中重用一些东西吗?

  • Would I need to write it all by myself?
  • 我需要自己写这些吗?

  • Is it possible to narrow down the Object lambda to something else that only captures lambdas?
  • 是否有可能将Object lambda缩小到仅捕获lambda的其他东西?

2 个解决方案

#1


24  

Marko's comment on the question is correct. You can't read a bare Java lambda expression out of a file, since such an expression isn't defined without a target type provided by the context. For example, consider the following method declarations:

Marko对这个问题的评论是正确的。您无法从文件中读取裸Java lambda表达式,因为如果没有上下文提供的目标类型,则不会定义此类表达式。例如,请考虑以下方法声明:

void method1(BiFunction f) { ... }
void method2(BiFunction f) { ... }

Then in the following code,

然后在下面的代码中,

method1((x, y) -> x + y);
method2((x, y) -> x + y);

the two lambda expressions (x, y) -> x + y mean completely different things. For method1, the + operator is string concatenation, but for method2, it means integer addition.

两个lambda表达式(x,y) - > x + y表示完全不同的东西。对于method1,+运算符是字符串连接,但对于method2,它表示整数加法。

This is wandering a bit far afield from your question, but you can read and evaluate a lambda or function expression using a dynamic language. In Java 8 there is the Nashorn Javascript engine. So instead of attempting to read an evaluate a Java lambda expression, you could read and evaluate a Javascript function using Nashorn, called from Java.

这在你的问题上有点偏远,但你可以使用动态语言阅读和评估lambda或函数表达式。在Java 8中有Nashorn Javascript引擎。因此,您可以使用从Java调用的Nashorn来读取和评估Javascript函数,而不是尝试读取评估Java lambda表达式。

The following code takes a function in arg[0] and applies it to each subsequent, printing the results:

以下代码采用arg [0]中的函数并将其应用于每个后续函数,打印结果:

import java.util.function.Function;
import javax.script.*;

public class ScriptFunction {
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        @SuppressWarnings("unchecked")
        Function

Still, you might find this technique useful if you have a need to evaluate expressions or functions read from a file.

但是,如果您需要评估从文件中读取的表达式或函数,您可能会发现此技术很有用。

#2


12  

I believe that using Nashorn Javascript engine mentioned in Stuart's answer is the best choice in most cases. However if, for some reason, it's desired to stay within the Java world I have recently created the LambdaFromString library that converts a String code to lambda at runtime.

我相信在大多数情况下,使用Stuart答案中提到的Nashorn Javascript引擎是最佳选择。但是,如果由于某种原因,我希望保持在Java世界中,我最近创建了LambdaFromString库,它在运行时将String代码转换为lambda。

When using that library the code doing what is specified in the question looks like this:

使用该库时,执行问题中指定的代码如下所示:

    List list = new ArrayList<>();
    list.addAll(Arrays.asList(1, 2, 3, 4, 5));

    LambdaFactory lambdaFactory = LambdaFactory.get();
    Function lambda = lambdaFactory
            .createLambda("x -> x + 1", new TypeReference>() {});
    list.stream().map(lambda).forEach(System.out::println); //prints 2 to 6

The only thing that differs is that the type of lambda has to be known and passed to the library so that the compiler knows what "+" means in this context.

唯一不同的是,必须知道lambda的类型并将其传递给库,以便编译器知道在此上下文中“+”的含义。


推荐阅读
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • 本文介绍了在Cpp中将字符串形式的数值转换为int或float等数值类型的方法,主要使用了strtol、strtod和strtoul函数。这些函数可以将以null结尾的字符串转换为long int、double或unsigned long类型的数值,且支持任意进制的字符串转换。相比之下,atoi函数只能转换十进制数值且没有错误返回。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
  • 本文介绍了关于Java异常的八大常见问题,包括异常管理的最佳做法、在try块中定义的变量不能用于catch或finally的原因以及为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的异常。同时指出这些问题是由于不同的开发人员开发所导致的,不值得过多思考。 ... [详细]
  • 本文介绍了在RHEL 7中的系统日志管理和网络管理。系统日志管理包括rsyslog和systemd-journal两种日志服务,分别介绍了它们的特点、配置文件和日志查询方式。网络管理主要介绍了使用nmcli命令查看和配置网络接口的方法,包括查看网卡信息、添加、修改和删除配置文件等操作。 ... [详细]
  • tcpdump 4.5.1 crash 深入分析
    tcpdump 4.5.1 crash 深入分析 ... [详细]
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼*madebyebhrz*#include#include#include#include#include#include#include ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
author-avatar
贴进你的心聆听你的世界
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有