Search code examples
javacollectionsclojureidiomsjava-interop

Converting Java collections to Clojure data structures


I am creating a Clojure interface to a Java API with a method that returns a java.util.LinkedHashSet.

Firstly, is the idiomatic Clojure way of handling this to convert the LinkedHashSet to a clojure data structure?

Secondly, what is the best method for converting Java collections into Clojure data structures?


Solution

  • There are lots of options, since Clojure plays very nicely with Java collections. It depends on exactly what data structure you want to use in Clojure.

    Here's some examples:

    ;; create a HashSet
    (def a (java.util.HashSet.))
    (dotimes [i 10] (.add a i))
    
    ;; Get all the values as a sequence 
    (seq a)
    => (0 1 2 3 4 5 6 7 8 9)
    
    ;; build a new HashSet containing the values from a 
    (into #{} a)
    #{0 1 2 3 4 5 6 7 8 9}
    
    ;; Just use the HashSet directly (high performance, no copy required)
    (.contains a 1)
    => true
    (.contains a 100)
    => false
    

    Regarding when to use each of these, I'd suggest the following advice:

    • If you are trying to wrap a Java library and present a clean Clojure API, then I'd suggest converting to the equivalent Clojure data structures. This is what Clojure users will expect, and you can hide the potentially messy Java interop details. As a bonus, this will make things immutable so that you don't run the risk of Java collections mutating while you use them.
    • If you just want to use the Java API quickly and efficiently, just use Java interop directly on the Java collections.