Search code examples
javaclojureclojure-java-interop

Use Java object as Clojure map


I have a Java class that I'd like to use in Clojure. But, I want to use it as a Clojure map. What are the steps required to do so?

I've looked at the code for IPersistentMap -- should the Java class implement that? Or should there be some Clojure code which implements a protocol?

I know I could just write some mapping code, to explicitly convert the code from Java objects to maps, but that solution has a high effort/reward ratio. Also, I might encounter this same situation many more times.


Concrete example: I have a parser written in Java. I'd like to use that to parse some text, and then access the contents of the parsed data structure as though it were in Clojure maps:

(def parser (new MyParser))

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

Solution

  • The function bean came to mind:

    Takes a Java object and returns a read-only implementation of the map abstraction based upon its JavaBean properties.

    Example taken from the site:

    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}