首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java对象作为Clojure映射

使用Java对象作为Clojure映射
EN

Stack Overflow用户
提问于 2011-10-27 13:01:33
回答 6查看 4.7K关注 0票数 16

我有一个Java类,我想在Clojure中使用它。但是,我想用它作为Clojure地图。为此需要采取哪些步骤?

我已经看过了IPersistentMap的代码-- Java类应该实现它吗?或者应该有一些Clojure代码来实现协议?

我知道我只需编写一些映射代码,就可以显式地将代码从Java对象转换为映射,但是该解决方案的工作量/回报比很高。而且,我可能会遇到更多同样的情况。

具体示例:我有一个用Java编写的解析器。我想使用它来解析一些文本,然后访问解析过的数据结构的内容,就好像它在Clojure映射中一样:

代码语言:javascript
复制
(def parser (new MyParser))

(let [parse-tree (parser ... parse some text ...)]
  ((parse-tree :items) "itemid"))
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-10-27 14:26:19

想到了函数bean

获取一个Java对象,并根据其JavaBean属性返回映射抽象的只读实现。

从站点获取的示例:

代码语言:javascript
复制
user=> (import java.util.Date)
java.util.Date

user=> (def *now* (Date.))
#'user/*now*

user=> (bean *now*)
{:seconds 57, :date 13, :class java.util.Date,
 :minutes 55, :hours 17, :year 110, :timezoneOffset -330,
 :month 6, :day 2, :time 1279023957492}
票数 24
EN

Stack Overflow用户

发布于 2012-08-26 15:28:11

当然,(bean javaObject) (参见豆ClojureDoc)运行良好,但它不允许您选择您想要的属性和不需要的属性。当您将结果映射输入json-str函数时,会产生影响,在这种情况下,您可能会得到一个错误:“不知道如何编写JSON of .”

当我处理基本上接受JSON的NoSQL DB (mongoDB,neo4j)时,我发现这很烦人(就像新保守主义的底层)。

那我的解决方案是什么?

代码语言:javascript
复制
(defmacro get-map-from-object-props [object & props]
  ;->> will eval and reorder the next list starting from the end
  (->> (identity props) ;identity is here to return the 'props' seq
       ;map each property with their name as key and the java object invocation as the value
       ;the ~@ is here to unsplice the few properties
       (map (fn [prop] [(keyword (str prop)) `(.. ~object ~@(prop-symbol prop) )]))
       (into {})))

;getter is a simple function that transform a property name to its getter "name" -> "getName"
(defn prop-symbol [prop]
  (map symbol (map getter (clojure.string/split (str prop) #"\\."))))

您可以这样使用它(是的,这个函数负责处理一个属性链(如果有的话))

代码语言:javascript
复制
(get-map-from-object-props javaObject property1 property2 property3.property1)

希望这能帮到某人。

票数 5
EN

Stack Overflow用户

发布于 2011-10-27 13:34:04

Clojure关键字可以在实现java.lang.Map接口所需(只读)部分的任何内容中查找内容。问题可能在于,您实际上并没有使用clojure关键字作为键,因此这可能对您没有帮助。

至于IPersistentMap,您的解析器可能没有实现与该接口相关的任何内容。

就我个人而言,我会写一个直接向上的转换函数。Clojure使用了很多这些(例如seq ),在转换之后,您知道您正在处理的是一个真正的持久映射,而不是只在某些时候执行类似操作的事情(因此您实际上可以在其上调用seq、key、vals等)。

另一种选择;

  • 只需实现clojure.lang.ILookup,并忽略其他所有内容。
  • 如果您想要更通用的东西,可以使用一些生成的/反射代码进行转换。有关示例,请参见https://github.com/joodie/clj-java-fields
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7916199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档