What is the Clojure-idiomatic way to convert a data structure to a Java collection, specifically:
[]
to a java.util.ArrayList
{}
to a java.util.HashMap
#{}
to a java.util.HashSet
()
to a java.util.LinkedList
Is there a clojure.contrib library to do this?
USE CASE: In order to ease Clojure into my organization, I am considering writing a unit-test suite for an all-Java REST server in Clojure. I have written part of the suite in Scala, but think that Clojure may be better because the macro support will reduce a lot of the boilerplate code (I need to test dozens of similar REST service calls).
I am using EasyMock to mock the database connections (is there a better way?) and my mocked methods need to return java.util.List<java.util.Map<String, Object>>
items (representing database row sets) to callers. I would pass in a [{ "first_name" "Joe" "last_name" "Smith" "date_of_birth" (date "1960-06-13") ... } ...]
structure to my mock and convert it to the required Java collection so that it can be returned to the caller in the expected format.
Clojure vector, set and list classes implement the java.util.Collection
interface and ArrayList
, HashSet
and LinkedList
can take a java.util.Collection
constructor argument. So you can simply do:
user=> (java.util.ArrayList. [1 2 3]) #<ArrayList [1, 2, 3]> user=> (.get (java.util.ArrayList. [1 2 3]) 0) 1
Similarly, Clojure map class implements java.util.Map
interface and HashMap
takes a java.util.Map
constructor argument. So:
user=> (java.util.HashMap. {"a" 1 "b" 2}) #<HashMap {b=2, a=1}> user=> (.get (java.util.HashMap. {"a" 1 "b" 2}) "a") 1
You can also do the reverse and it is much easier:
ser=> (into [] (java.util.ArrayList. [1 2 3])) [1 2 3] user=> (into #{} (java.util.HashSet. #{1 2 3})) #{1 2 3} user=> (into '() (java.util.LinkedList. '(1 2 3))) (3 2 1) user=> (into {} (java.util.HashMap. {:a 1 :b 2})) {:b 2, :a 1}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With