当前位置: 首页 > 面试题库 >

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

姚棋
2023-03-14
问题内容

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

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

此外,我们还有Integers 的列表:

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

有没有办法将Strings(x -> x + 1等)转换为Object代表lambda表达式的s?然后可以用作:

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);
}

我将如何编写这样的方法getLambdaFromString

  • 我可以从JDK / JRE中重用吗?
  • 我需要自己编写所有内容吗?
  • 是否有可能将范围缩小Object lambda到仅捕获lambda的其他内容?

问题答案:

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

void method1(BiFunction<String,String,String> f) { ... }
void method2(BiFunction<Integer,Integer,Integer> f) { ... }

然后在以下代码中,

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

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

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

以下代码在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<Object,Object> f = (Function<Object,Object>)engine.eval(
            String.format("new java.util.function.Function(%s)", args[0]));
        for (int i = 1; i < args.length; i++) {
            System.out.println(f.apply(args[i]));
        }
    }
}

例如,运行命令

java ScriptFunction 'function(x) 3 * x + 1' 17 23 47

给出结果

52.0
70.0
142.0

new java.util.function.Function为了在Nashorn的JavaScript函数概念和Java的Function接口之间创建一个适配器,必须在函数字符串内部进行包装。(也许有更好的方法,但我不知道。)将返回值强制转换为evalto会Function<Object,Object>导致未经检查的强制转换警告,我认为这是不可避免的,因为这是JavaScript(动态)类型语言和Java(静态类型)。最后,不执行任何错误检查。我敢肯定,如果违反某些假设(例如第一个参数实际上并不代表JavaScript函数),那么它将以各种讨厌的方式爆炸。

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



 类似资料:
  • 问题内容: 如何使用Python将列表转换为字符串? 问题答案: 通过使用 或者,如果列表是整数,则在连接元素之前将其转换。

  • 我有一个简单的行星名称数组,我想反转添加到数组中的每个名称(而不是字符串顺序)。 我仍在努力使用lambda语法: 目前我得到: 这条线上有多个标记 类型中的方法不适用于参数 类型不匹配:无法从转换为 谢谢大家的建议。。。asList让我接近了。我仍然没有正确分类。 所以我需要找到一种方法,使array.sort工作,因为这是任务(array.sort和lambda它)。 我已经打电话给老师要求澄

  • 使用Java 8 lambda语法将“key:value”形式的字符串数组转换为是否有更好的功能方法? 我现在的解决方案似乎并不实用:

  • 问题内容: 我正在阅读有关python的新f字符串的 博客 ,它们看起来很整洁。但是,我希望能够从字符串或文件中加载f字符串。 我似乎找不到任何执行此操作的字符串方法或其他函数。 从上面我的链接中的示例: 但是,如果我有琴弦怎么办?我希望能够像这样: 事实证明,我已经可以执行类似的操作并获得性能提高。即: 问题答案: f字符串是代码。不仅以安全的方式(当然,字符串文字就是代码),而且以危险的任意代

  • 问题内容: 我有一个,我需要一个。如何从一个转换为另一个? 问题答案: 好问题。我有以下五种 6种方法可以做到这一点。 注意:返回。因此有效地两者是相同的。 调用,这又设置了数组。 另一方面,调用以下程序包私有构造函数。 从源代码中的Java 8的源代码 因此似乎是最有效的方法,在这两个存储器和速度方面,用于转换char到String。

  • 我在JavaFX上有一个应用程序。在这个应用程序中,我需要实现专栏的编辑器。在旧版本中,该代码运行良好: 但是当我试图用lambda重写代码时 我得到一个错误:错误:java:不兼容的类型:lambda表达式中的不兼容参数类型告诉我如何指定lambda表达式的类型?