java - Java中的lambda函数树?
问题描述
我正在移植一些软件,它可以在 Swift 和 JavaScript 中运行,但我无法弄清楚如何在 Java 中进行。
JavaScript 版本如下所示:
var obj = { "A": {
"1": (params) => { console.log("A1", params); },
"2": (params) => { console.log("A2", params); }
}, // A
"B": {
"1": (params) => { console.log("B1", params); },
"2": (params) => { console.log("B2", params);}
}, //B
}; // obj
在运行时,应用程序引擎调用
var a = 'A';
var i = '2';
obj[a][i](params);
我一生都无法弄清楚如何在 Java 中做到这一点。一个关键约束(没有双关语)是代码必须在结构上与其他端口相似。
以前,我试图使用 Object[][],
Map<String, Object> map = Stream.of(obj).collect(Collectors.toMap(data -> (String) data[0], data -> (Object) data[1]));
能够嵌入一些 Map<String, Integer> 对象。例子:
Map<String, Integer> colorMap = Stream.of(new Object[][] {
{"black", 0x000000},
{"navy", 0x000080},
};
我试图得出类似的代码,但 Java 不喜欢它,因为 lambdas 和 Object 不兼容。
我希望得到的代码是:
Map<String, Map<String, Callable<Void> > > obj = Stream.of(new Object[][] {
{"A", Stream.of(new Object[][] {
{"1", (params)->{ System.out.println("A1"); } },
{"2", (params)->{ System.out.println("A2"); } } }),
{"B", Stream.of(new Object[][] {
{"1", (params)->{ System.out.println("B1"); } },
{"2", (params)->{ System.out.println("B2"); } } } )}
}
});
...
// call the function (assuming A and 1 exist)
obj.get("A").get("1")(params);
但我对如何将其转换为能够使用 lambdas 感到困惑。我不断收到的错误是:
error: incompatible types: Object is not a functional interface
或error: lambda expression not expected here
解决方案
一种可能的 Java 结构保留翻译是:
Map<String, Map<String, Runnable>> obj = Map.of(
"A", Map.of(
"1", () -> System.out.println("A1"),
"2", () -> System.out.println("A2")
),
"B", Map.of(
"1", () -> System.out.println("B1"),
"2", () -> System.out.println("B2")
)
);
你像这样使用它:
obj.get("A").get("2").run();
如果您需要传递参数或从函数返回值,请替换Runnable
为不同的函数接口。您可能必须定义自己的一个。例如:
@FunctionalInterface
interface FunctionWithObjectParameters {
void run(Object... args);
}
更新:如果您需要在 Java 8 中执行此操作,一种选择是使用具有以更方便的方式构建地图的方法的外部库 - 例如guava collect。
另一种选择是自己实现便利方法。Map.of
不做任何魔术,您可以轻松地将其替换为您自己的“mapOf”方法:
static <K, V> Map<K, V> mapOf(K key1, V value1) {
return mapOfEntries(entry(key1, value1));
}
static <K, V> Map<K, V> mapOf(K key1, V value1, K key2, V value2) {
return mapOfEntries(entry(key1, value1), entry(key2, value2));
}
static <K, V> Map<K, V> mapOf(K key1, V value1, K key2, V value2, K key3, V value3) {
return mapOfEntries(entry(key1, value1), entry(key2, value2), entry(key3, value3));
}
// Add more overloads if you need
static <K, V> Map<K, V> mapOfEntries(Map.Entry<K, V>... args) {
// On Android, you may want to use ArrayMap instead of HashMap
Map<K, V> map = new HashMap<>();
for (Map.Entry<K, V> arg : args) {
map.put(arg.getKey(), arg.getValue());
}
return map;
}
static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
推荐阅读
- aws-api-gateway - 使用来自身份服务器的访问令牌访问 AWS API 网关
- java - 选择联系人并在recyclerview中显示
- php - Easy Google Fonts Wordpress 插件不支持免费主题 Parallaxsome
- windows - 在 Windows bash 中处理命令响应
- ios - 在 iOS 中基于 scheme 管理 Pod
- c# - 用户控件并从放置在用户控件中的控件引发事件
- nginx - 在 NGINX 后面时所有网站链接都断开
- java - Java.lang.classnotfoundexception - HelloWorld.class
- javascript - 当应用程序在虚拟文件夹中运行时,Webpack 不加载脚本
- python - 无法重命名熊猫 DataFrame 中的第一列