我一直认为套装没有订购,但注意到 字符集似乎是有序的:
(seq #{\e \c \b \z \a})
=> (\a \b \c \e \z)
如果我介绍其他类型的字符,似乎它们是按照字符代码排序的:
(seq #{\e \A \c \space \b \z \a})
=> (\space \A \a \b \c \e \z)
为什么根据代码对字符进行排序,但是数字集似乎有任意顺序?
答案 0 :(得分:10)
这是因为Character/hashCode
与角色的序号直接相关,而集合则基于散列图。但是如果你引入了足够多的字符来开始获得哈希冲突,那么表观排序并不能完全结合在一起:
; the whole alphabet is small enough to avoid collisions
user=> (apply str (set "abcdefghijklmnopqrstuvwxyz"))
"abcdefghijklmnopqrstuvwxyz"
; and observe the hashes are indeed sequential
user=> (map hash (set "abcdefghijklmnopqrstuvwxyz"))
(97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122)
; but go from 26 to 36 elements, and you start to see collisions
user=> (apply str (set "0123456789abcdefghijklmnopqrstuvwxyz"))
"abcdefghijklmno0p1q2r3s4t5u6v7w8x9yz"
user=> (map hash (set "0123456789abcdefghijklmnopqrstuvwxyz"))
(97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 48 112 49 113 50 114 51 115 52 116 53 117 54 118 55 119 56 120 57 121 122)
但是当然,如您所知,这不是一个已定义的行为,而是当前实施的工作方式。
现在,你问为什么数字不会发生这种情况:原因是,Clojure明确地避免了它! (.hashCode 1)
返回1,因为Java是如何定义其哈希码的。但是Clojure's hash
function使用的是murmur3,它返回的数字值完全不同于返回输入:(hash 1)
得到1392991556.我不是这方面的专家,但我相信使用杂音的主要动机而不是Java的内置散列函数是出于安全原因避免散列冲突。时间攻击还是什么?