Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: working with a java.util.HashMap in an idiomatic Clojure fashion

I have a java.util.HashMap object m (a return value from a call to Java code) and I'd like to get a new map with an additional key-value pair.

If m were a Clojure map, I could use:

(assoc m "key" "value") 

But trying that on a HashMap gives:

java.lang.ClassCastException: java.util.HashMap cannot be cast to clojure.lang.Associative

No luck with seq either:

(assoc (seq m) "key" "value") 

java.lang.ClassCastException: clojure.lang.IteratorSeq cannot be cast to clojure.lang.Associative

The only way I managed to do it was to use HashMap's own put, but that returns void so I have to explicitly return m:

(do (. m put "key" "value") m) 

This is not idiomatic Clojure code, plus I'm modifying m instead of creating a new map.

How to work with a HashMap in a more Clojure-ish way?

like image 609
foxdonut Avatar asked Nov 03 '09 03:11

foxdonut


1 Answers

Clojure makes the java Collections seq-able, so you can directly use the Clojure sequence functions on the java.util.HashMap.

But assoc expects a clojure.lang.Associative so you'll have to first convert the java.util.HashMap to that:

(assoc (zipmap (.keySet m) (.values m)) "key" "value") 

Edit: simpler solution:

(assoc (into {} m) "key" "value") 
like image 115
Siddhartha Reddy Avatar answered Nov 12 '22 18:11

Siddhartha Reddy