`hash` is Clojure’s default hashing function. It matters when values—including collections—serve as keys in hash maps: Java’s `hashCode()` alone can perform poorly for some composite keys. section 6.0 section 6.6
`(hash x)` accepts any object, including `nil`, and returns a signed 32-bit `java.lang.Integer`. Numbers, strings, and values implementing `clojure.lang.IHashEq` follow Clojure hashing rules; for other values, `hash` delegates to Java’s `.hashCode()`. section 6.6
A basic result
`(hash "hello")` returns `1715862179`; `(type (hash "hello"))` returns `java.lang.Integer`. Distinct values can still share a hash: the numeric values `-1` and `0`, for example, both have Java `hashCode` value `0` in the illustrated comparison, but different Clojure `hash` results. section 6.6
The related helpers address collection hashing directly. `hash-ordered-coll` accounts for element order; `hash-unordered-coll` does not. Both require a `java.lang.Iterable`: passing `nil` raises `NullPointerException`, while a non-iterable value raises `ClassCastException`. `mix-collection-hash` takes a hash basis and a count when integrating collection hashes. section 6.6
(=
(hash-unordered-coll [1 2 3]) ; #1
(hash-unordered-coll [3 2 1])
(hash-unordered-coll #{1 2 3}))
;; true
(=
(hash-ordered-coll [1 2 3]) ; #2
(hash-ordered-coll [3 2 1])
(hash-ordered-coll #{1 2 3}))
;; false
Compare the same elements in different orders: their unordered collection hashes agree, while their ordered collection hashes do not. section 6.6
Equality and hashing need attention at Java interop boundaries. A Java `ArrayList` and a Clojure vector can compare equal yet produce different results from `hash`; a Java `HashMap` also cannot be passed directly to `hash-unordered-coll` because it is not `Iterable`. For that map case, hashing its entries and mixing in their count produces the illustrated Clojure-map hash. section 6.6
(defn hash-java-map [^java.util.Map m]
(let [iter (.. m entrySet iterator)] ; #1
(loop [ret 0 cnt 0]
(if (.hasNext iter)
(let [^java.util.Map$Entry item (.next iter) ; #2
kv [(.getKey item) (.getValue item)]]
(recur
(unchecked-add ret ^int (hash kv)) ; #3
(unchecked-inc cnt)))
(.intValue ^Long (mix-collection-hash ret cnt)))))) ; #4
(= (hash (HashMap. {1 2 3 4})) ; #5
(hash {1 2 3 4}))
;; false
(= (hash-java-map (HashMap. {1 2 3 4})) ; #6
(hash {1 2 3 4}))
;; true
The Java-map example shows entry iteration, `hash` on key-value pairs, `unchecked-add` for accumulation, and `mix-collection-hash` for the final result. section 6.6 section 5.13
