Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Clojure data structures to Java collections

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.

like image 573
Ralph Avatar asked Nov 30 '10 12:11

Ralph


1 Answers

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} 
like image 84
Abhinav Sarkar Avatar answered Sep 20 '22 04:09

Abhinav Sarkar