Be super-careful doing this. Java's array equality and hashCode are correct: since arrays are mutable, they are not values. So equals and hashCode are correctly identity-based.
Also, 1.2's vector-of lets you have vectors of primitives, which may give you the perf you need. But, if you can ensure that the arrays will be used as values: (ns key (:require [clojure.string :as str])) (deftype Key [key] Object (equals [this other] (if (= (class this) (class other)) (java.util.Arrays/equals ^ints key ^ints (.key ^Key other)) false)) (hashCode [this] (java.util.Arrays/hashCode ^ints key)) (toString [this] (str/join \, (seq key)))) (defn int-key [coll] (Key. (int-array (count coll) coll))) Stu Stuart Halloway Clojure/core http://clojure.com > If you don't do anything special, and create several Java array of bytes (for > example) and use them as keys in a Clojure map, the default hashCode and > equals implementation will cause two arrays with identical contents to be > treated as different keys in the map, unless they are also == in Java. > > I'd like to use Java byte arrays as keys in Clojure maps, but haven't been > able to figure out how yet. I know that java.util.Arrays/hashCode and > java.util.Arrays/equals have the behavior I want, so one way would be to get > Clojure to somehow use those methods when given the byte arrays as keys. > That led me to think of trying deftype to make my own type Key with the > desired implementation of hashCode and equals. I'm using Clojure 1.2, and I > don't see how to give the appropriate type hints to declare that something is > a Java byte array. Here is one attempt for Java int arrays instead of Java > byte arrays: > > (definterface IKey > (^ints key []) > (equals [other-key] "Compare two Keys for value equality, i.e. same length > and same bytes in array value") > (hashCode [] "Return a hash code that is the same for equal keys, and > usually different for different keys")) > > > (deftype Key [^ints key] > IKey > (key [this] key) > (equals [this other-key] > (let [^Key other other-key] > (java.util.Arrays/equals key (.key other)))) > (hashCode [this] > (java.util.Arrays/hashCode key)) > > Object > (toString [this] > (apply str (map char key)))) > > When I try to evaluate the deftype statement, I get an error like this: > > java.lang.NoClassDefFoundError: java/lang/ints > > Same error if I replace ^ints with #^ints. If I leave out the type hints for > the field key completely, I get the following error when trying to evaluate > the deftype: > > java.lang.VerifyError: (class: user/Key, method: hashCode signature: > ()Ljava/lang/Object;) Expecting to find object/array on stack > > I'm not wedded to deftype as being part of the solution. My real goal is as > high performance way of using Java byte/int/some-native-type arrays as map > keys, i.e. with no reflection warnings. > > Thanks, > Andy > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en