Converting Clojure data structures to Java collections

14,331

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}
Share:
14,331
Ralph
Author by

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, 2022

Comments

  • Ralph
    Ralph almost 2 years

    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.

  • Ralph
    Ralph over 13 years
    I did not know that. That's perfect. Thanks.
  • Andre Steingress
    Andre Steingress over 10 years
    Just 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.