store/[org.clojure/clojure "1.8.0"] clj::clojure.core/hash

Community Documentation


hash returns a 32-bit integer hash value for any object. It is similar to Java's hashCode, but it is consistent with Clojure clj::clojure.core/= (with a few exceptions – see below). hashCode is consistent with Java's equals method.

When we say a hash function is consistent with =, it means that for any two values x1 and x2 where (= x1 x2) is true, (= (hash x1) (hash x2)) is also true. This is an important property that allows hash to be used in the implementation of the hash-set and hash-map data structures.

hash is consistent with =, except for some BigIntegers, Floats, and Doubles. This leads to incorrect behavior if you use them as set elements or map keys (see example below). Convert BigIntegers to BigInt using (bigint x), and floats and doubles to a common type with (float x) or (double x), to avoid this issue. This behavior is by choice:

See also: (topic Equality)


(defn hash
  "Returns the hash code of its argument. Note this is the hash code
  consistent with =, and thus is different than .hashCode for Integer,
  Short, Byte and Clojure collections."

  {:added "1.0"
   :static true}
  [x] (. clojure.lang.Util (hasheq x)))

Example 1

(def x 8589934588)
;; => #'user/x
(= (bigint x) (biginteger x))
;; => true

;; hash is not consistent with = for all BigInteger values
(= (hash (bigint x)) (hash (biginteger x)))
;; => false

(def s1 (hash-set (bigint x)))
;; => #'user/s1

(def s2 (hash-set (biginteger x)))
;; => #'user/s2

;; s1 and s2 look the same
;; => #{8589934588N}

;; =>  #{8589934588}

;; their elements are =
(= (first s1) (first s2))
;; => true

;; However, the sets are not = because of hash inconsistency.
(= s1 s2)
;; => false

Example 2

(= (float 1.0e9)
   (double 1.0e9))
;; => true

;; hash is not consistent with = for all float/double values

(= (hash (float 1.0e9))
   (hash (double 1.0e9)))
;; => false

Example 3

(hash "a")
;; => 97

(.hashCode "a")  ; notice it is the same hash as java.lang.String.hashCode()
;; => 97

(hash [1 2 3])
;; => 30817

(hash [1 2 3 4])
;; => 955331

Uses on crossclj