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?
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")