我在为arraylist返回的hashcode中遇到了一个奇怪的问题。下面是修改后的tuple.clj(来自ApacheStorm源代码)。传递给列表哈希代码的列表是字符串列表。返回的哈希代码(返回的代码为%6)总是4。i、 e.“(mod(.hashcode)6)”始终为4。我真的很困惑到底出了什么问题。由于这个问题,跨下一个bolt任务的元组分布是不正确的。我不知道这里可能出了什么问题。同样的问题,我不认为我运行的东西从clojure repl。
我如何知道正在使用哪个hashcode函数?有没有办法检查clojure的java类方法的方法细节?
(ns backtype.storm.tuple
(:use [backtype.storm bootstrap])
)
(bootstrap)
(defn- print-comma-list [^List els ]
(let [ret (StringBuilder. ) ]
(do
(loop [iter (.iterator els) ]
(when (.hasNext iter)
(.append (.append ret (.next iter)) ",")
(recur iter))))
(.toString ret)))
(defn list-hash-code [^List alist comp-id group-id ]
(do
(if ( and (= comp-id "test1-bolt") ( = group-id "field1,"))
(log-message "Hashcode returned: " (.hashCode alist) " mod val " (mod (.hashCode alist) 6) " " (print-comma-list alist)))
(.hashCode alist)))
2条答案
按热度按时间wgmfuz8q1#
实施
hashcode
对于javaArrayList
完全不是“随机的”。它实际上使用的是java中指定的算法
List
以可预测的方式组合元素哈希代码的api;看看这个javadoc。如果列表的元素具有可预测的顺序和可预测的哈希码,则列表哈希码是可预测的。算法如下(在java中):
有没有办法检查clojure的java类方法的方法细节?
java源代码和javadocs是免费提供的。
但是,不支持从clojure检查“方法详细信息”。。。假设您感兴趣的“方法细节”是算法(实际上,java程序也不支持它!)我想,您可以通过编程查找字节码,并调用一些应用程序来反汇编或反编译它们。但没什么意义。。。考虑到
java.util.*
包含在每个oracle jdk安装程序中。kmbjn2e32#
如果调用.getclass.getcanonicalname,将获得实现所使用列表的类的全名。oraclejdk中默认抽象列表的hashcode包含在stephen c.的答案中。如果这是所使用的源代码,那么如果字符串不同,就不会有特殊的异常原因,尽管这取决于您的数据。
请注意,hashcode()根本不能保证均匀分布。只要equals()函数区分类的不同示例,hashcode()为类的所有示例返回1是正确的。这是因为hashcode表示“弱相等”,相等的对象必须具有相同的hashcode(例如,要通过hashmap正确找到),但反之则不成立。这意味着您可以将hashcode修改为其他内容,例如list,hashcode乘以一个素数,只要从旧hashcode到新hashcode的函数将相同的输入Map到相同的输出(没有随机元素)。