使用Clojure在Java对象上调用方法列表

使用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

我有一个要转换为不可变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 [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)]