Working with Java Arrays

One improvement that I’d like to see in Clojure is more examples in the doc strings (or maybe in a separate :example metadata item). Still, nothing to stop me building up a set of my own.

So, here are some simple examples of working with Java arrays in Clojure…

Given some sample data:

(def my-list '(1 2 3 4 5))
(def my-vector [1 2 3 4 5])
(def my-map {:a "apple" :b "banana" :c "chopped liver"})

To convert to Java arrays:

(to-array my-list)
#<Object[] [Ljava.lang.Object;@962522b>
(to-array my-vector)
#<Object[] [Ljava.lang.Object;@37e55794>
(to-array my-map)
#<Object[] [Ljava.lang.Object;@52cd19d>

Note that this always returns Object[] regardless of the contents of the collection. Note also that the map isn’t flattened (the pp function used here is in clojure.contrib.pprint):

user=> (pp)
[[:a "apple"], [:b "banana"], [:c "chopped liver"]]

If the array is 2-dimensional there is a corresponding function:

user=> (def my-vec-2d [[1 2 3] [4 5 6] [7 8 9]])
#'user/my-vec-2d
user=> (to-array-2d my-vec-2d)
#<Object[][] [[Ljava.lang.Object;@3a42f352>
user=> (pp)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
nil

If you need to use a specific type of array (e.g. to pass a String[] into a Java method) or need to use an array with more than 3 dimensions it’s a little trickier:

user=> (into-array my-list)
#<Integer[] [Ljava.lang.Integer;@60c0c8b5>
user=> (pp)
[1, 2, 3, 4, 5]
nil
user=> (into-array my-vector)
#<Integer[] [Ljava.lang.Integer;@2151b0a5>
user=> (pp)
[1, 2, 3, 4, 5]
nil
user=> (into-array my-map)
#<MapEntry[] [Lclojure.lang.MapEntry;@7ae0c7c3>
user=> (into-array (vals my-map))
#<String[] [Ljava.lang.String;@731de9b>
user=> (pp)
["apple", "banana", "chopped liver"]
nil

There, that should serve as a handy reference for myself for when I’m feeling forgetful…

  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati

3 Comments so far

  1. […] with Java Arrays – Clojure (here, via @hkrnws) — This article explains how to transform Clojure data structures into java […]

  2. nick on January 16th, 2010

    How does one specify an array as the parameter to a constructor in a gen-class scenario? I’d like to extend a class which has multiple single-argument constructors, some of which are of type Class[]. What would that look like in clojure?

  3. Ian Phillips on January 17th, 2010

    Hmm, I’m not actually sure. I’ve just tried running what I thought was the correct solution in a REPL and it doesn’t work, so you’re going to have to give me a day or two to come up with the correct answer.

Leave a Reply