test = 'a'
test2 = '@a'.slice(0)
test3 = '@a'[1]
puts test.hash
puts test2.hash
puts test3.hash
100
64
97
這是bug還是我誤解散列法是如何工作的?有沒有辦法來解決這個問題?
test = 'a'
test2 = '@a'.slice(0)
test3 = '@a'[1]
puts test.hash
puts test2.hash
puts test3.hash
100
64
97
這是bug還是我誤解散列法是如何工作的?有沒有辦法來解決這個問題?
這些表達式的結果並不都是相同的數據。 Ruby 1.8整數包含單個字符索引的字符數字。這已在Ruby 1.9中更改,但slice(0)
返回字符串'@'
的第一個字符,而不是'a'
。
在Ruby 1.8(使用irb
):
irb(main):001:0> test = 'a'
=> "a"
irb(main):002:0> test2 = '@a'.slice(0)
=> 64
irb(main):003:0> test3 = '@a'[1]
=> 97
irb(main):004:0> test.hash
=> 100
irb(main):005:0> test2.hash
=> 129
irb(main):006:0> test3.hash
=> 195
在Ruby 1.9.1:
irb(main):001:0> test = 'a'
=> "a"
irb(main):002:0> test2 = '@a'.slice(0)
=> "@"
irb(main):003:0> test3 = '@a'[1]
=> "a"
irb(main):004:0> test.hash
=> 1365935838
irb(main):005:0> test2.hash
=> 347394336
irb(main):006:0> test3.hash
=> 1365935838
原因是每個變量引用不同的對象與自己唯一的哈希碼!變量test
是字符串「a」,test2
是整數64(字符數字'@'),並且test3
是整數97('a')。令人驚訝的是,在Ruby中,字符串的元素是整數,而不是字符串或字符。
由於maerics指出,除非已經定義了你自己的哈希方法的類,你'使用哈希可能只是在對象本身,而不是它的內容。也就是說,你可以(也應該)爲你定義一個equals方法的類定義你自己的散列方法。
在Ruby中,String類已經這樣做了你:
irb(main):001:0> test="a"
=> "a"
irb(main):002:0> test2="a"
=> "a"
irb(main):003:0> test.hash
=> 100
irb(main):004:0> test2.hash
=> 100
irb(main):005:0> test2[0]=test.slice(0)
=> 97
irb(main):006:0> test2
=> "a"
irb(main):007:0> test2.hash
=> 100
我還沒有找到一個Ruby等效文本,但關於Java這個頁面給出了生成自己的散列碼是一個很好的算法不難複製Ruby:http://www.javapractices.com/topic/TopicAction.do?Id=28