Converting Clojure data structures to Java collections
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}
Ralph
Physician, retired. Retired software engineer/developer (Master of Science in Computer Science). I currently program mostly in Go. I am particularly interested in functional programming. In past lives, I programmed in Java, Scala, Basic, Fortran, Pascal, Forth, C (extensively, at Bell Labs), C++, Groovy, and various assembly languages. Started programming in assembly language in 1976. I started a martial arts school in 1986 (Shojin Cuong Nhu in New Jersey) and currently teach at the Tallest Tree Dojo in Gainesville, Florida. I like to cook. I am an atheist. Email: user: grk, host: usa.net
Updated on June 06, 2022Comments
-
Ralph almost 2 years
What is the Clojure-idiomatic way to convert a data structure to a Java collection, specifically:
[]
to ajava.util.ArrayList
{}
to ajava.util.HashMap
#{}
to ajava.util.HashSet
()
to ajava.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. -
Ralph over 13 yearsI did not know that. That's perfect. Thanks.
-
Andre Steingress over 10 yearsJust in case it is needed to transform keyword keys in a Clojure map to strings you could use "stringify-keys" which can also be found in clojure.walk.