我有一个我想要转换为不可变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
返回预期值:
{.latitude 49.0, .longitude 11.1, .altitude 150.0}
但是reduce-kv
只返回我的最后一个值:
150.0
为什么我不回复构建器,然后我可以应用.build
方法?我曾期望reduce-kv
与以下代码具有相同的结果,返回我期望的结果:
(.build (.altitude (.longitude (.latitude (pkg.Position/builder) 150.0) 11.1) 49.0))
由于reduce-kv
函数返回一个双精度,以下调用.build
失败
No matching field found: build for class java.lang.Double
BTW:我将方法映射到列表值的原因是,我必须设置的实际字段列表比示例中的更长。在保留基本问题的同时,我删除了示例以使其更具可读性。
答案 0 :(得分:3)
虽然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)]