使用Clojure在Java对象上调用方法列表
我有一个要转换为不可变Java POJO的值列表。JavaPOJO是使用构建器模式生成的 我的名单如下:使用Clojure在Java对象上调用方法列表,clojure,clojure-java-interop,Clojure,Clojure Java Interop,我有一个要转换为不可变Java POJO的值列表。JavaPOJO是使用构建器模式生成的 我的名单如下: [49.0 11.1 150.0] 在Java中,我的POJO的构造如下: Position.builder().latitude(49.0).longitude(11.1).altitude(150.0).build() 我想在Clojure中创建它,首先我将zipmap需要使用的方法的值,然后我可以将kv所有东西减少到我需要的Java值: (defn poslist->map
[49.0 11.1 150.0]
在Java中,我的POJO的构造如下:
Position.builder().latitude(49.0).longitude(11.1).altitude(150.0).build()
我想在Clojure中创建它,首先我将zipmap
需要使用的方法的值,然后我可以将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
顺便说一句:我将方法映射到列表值的原因是,我必须设置的字段的实际列表比示例中更长。在保留基本问题的同时,我简化了示例以使其更具可读性。虽然使用Clojure符号,但它们与同名函数没有任何联系:
> ('.add (java.util.ArrayList.) 1)
1
> ('first [1 2 3])
nil
> ('conj [1 2] 3)
3
因此,问题基本上是根本不调用java方法。要修复此问题,请使用以下内容包装您的iterop方法:
或者,正如@noisesmith所建议的,使用clojure函数:
->
[#(.latitude %1 %2) #(.longitude %1 %2) #(.altitude %1 %2)]
目前没有任何情况下
(memfn foo)
比#(.foo%)
更可取,谢谢你们,这很有效!请注意:为了完全匹配我的问题,创建的函数需要两个参数(生成器实例和要设置的值)。因此它要么是(memfn latitude val)
要么是#(.latitude%1%2)
。
->
[#(.latitude %1 %2) #(.longitude %1 %2) #(.altitude %1 %2)]