使用 Clojure 在 Java 对象上调用方法列表
Calling a list of methods on a Java object using Clojure
我有一个要转换为不可变 Java POJO 的值列表。 Java POJO 使用构建器模式生成。
我的列表是:
[49.0 11.1 150.0]
在 Java 中,我的 POJO 将像这样构建:
Position.builder().latitude(49.0).longitude(11.1).altitude(150.0).build()
我想在 Clojure 中创建它,我首先 zipmap
需要使用的方法的值,然后我可以 reduce-kv
一切到我需要的 Java 值:
(defn poslist->map [list]
(zipmap ['.latitude '.longitude '.altitude]
list))
(.build (reduce-kv #(%2 %1 %3)
(pkg.Position/builder)
(poslist->map list)))
我现在的问题是我没有得到我期望的结果。函数poslist->map
returns期望值:
{.latitude 49.0, .longitude 11.1, .altitude 150.0}
但是 reduce-kv
只是 returns 我拥有的最后一个值:
150.0
为什么我不取回可以应用 .build
方法的构建器?我曾预计 reduce-kv
与以下代码具有相同的结果 returns 我所期望的结果:
(.build (.altitude (.longitude (.latitude (pkg.Position/builder) 150.0) 11.1) 49.0))
并且作为 reduce-kv
函数 returns 以下对 .build
的双重调用失败
No matching field found: build for class java.lang.Double
顺便说一句:我将方法映射到列表值的原因是,我必须设置的实际字段列表比示例中的更长。我在保留基本问题的同时精简了示例以提高可读性。
虽然 Clojure 符号 act as functions,但它们与同名函数没有任何关联:
> ('.add (java.util.ArrayList.) 1)
1
> ('first [1 2 3])
nil
> ('conj [1 2] 3)
3
所以问题基本上是根本没有调用 java 方法。要修复它,请使用 memfn
:
包装您的 iterop 方法
['.latitude '.longitude '.altitude]
->
[(memfn latitude val) (memfn longitude val) (memfn altitude val)]
或者,正如@noisesmith 建议的那样,使用 clojure 函数:
->
[#(.latitude %1 %2) #(.longitude %1 %2) #(.altitude %1 %2)]
我有一个要转换为不可变 Java POJO 的值列表。 Java POJO 使用构建器模式生成。
我的列表是:
[49.0 11.1 150.0]
在 Java 中,我的 POJO 将像这样构建:
Position.builder().latitude(49.0).longitude(11.1).altitude(150.0).build()
我想在 Clojure 中创建它,我首先 zipmap
需要使用的方法的值,然后我可以 reduce-kv
一切到我需要的 Java 值:
(defn poslist->map [list]
(zipmap ['.latitude '.longitude '.altitude]
list))
(.build (reduce-kv #(%2 %1 %3)
(pkg.Position/builder)
(poslist->map list)))
我现在的问题是我没有得到我期望的结果。函数poslist->map
returns期望值:
{.latitude 49.0, .longitude 11.1, .altitude 150.0}
但是 reduce-kv
只是 returns 我拥有的最后一个值:
150.0
为什么我不取回可以应用 .build
方法的构建器?我曾预计 reduce-kv
与以下代码具有相同的结果 returns 我所期望的结果:
(.build (.altitude (.longitude (.latitude (pkg.Position/builder) 150.0) 11.1) 49.0))
并且作为 reduce-kv
函数 returns 以下对 .build
的双重调用失败
No matching field found: build for class java.lang.Double
顺便说一句:我将方法映射到列表值的原因是,我必须设置的实际字段列表比示例中的更长。我在保留基本问题的同时精简了示例以提高可读性。
虽然 Clojure 符号 act as functions,但它们与同名函数没有任何关联:
> ('.add (java.util.ArrayList.) 1)
1
> ('first [1 2 3])
nil
> ('conj [1 2] 3)
3
所以问题基本上是根本没有调用 java 方法。要修复它,请使用 memfn
:
['.latitude '.longitude '.altitude]
->
[(memfn latitude val) (memfn longitude val) (memfn altitude val)]
或者,正如@noisesmith 建议的那样,使用 clojure 函数:
->
[#(.latitude %1 %2) #(.longitude %1 %2) #(.altitude %1 %2)]