2012-01-16 43 views
0

嗨,大家好:我试图扫描一些对象,看看是否有任何重复。为此,我使用hashCode字段。对象以二进制文件序列化。在对象集合中递增递增的哈希代码

它看起来像这样:

的hashCode = 26594 的hashCode = 26595 的hashCode = 26596 ...

我绝不会想到,从一个集合哈希码会呈现这样的格局,除非JVM或在某些情况下(或者,内部创建的每个对象都有一个设置为静态增量值的hashCode),thrift会为某些对象随时创建hashCode。

当然,这个问题在这一点上没有明确的答案 - 但是,一般来说,是否有一个原因或常见的情况下,一个对象流会递增增加hashCodes?也许如果过去有人看到过这种现象,它可能会帮助我阐明我想了解的二进制文件。

  • 小细节:这些对象是使用Apache thrift库进行二进制序列化的,它们完全是在java/hadoop中读取/写入的。
+1

他们从哪里连载?如果他们在一个排序的集合中,那么订购它们是很自然的。至于值:哈希码由对象数据计算,与生成顺序无关。 – Viruzzo 2012-01-16 15:15:38

+1

我认为这取决于如何为对象定义'hashCode'方法? – 2012-01-16 15:19:30

+1

你已经给出了最可能的原因;散列码是一个增量ID。节俭可以采用散列码生成策略(IIRC)。不确定Hadoop如何处理它。 – 2012-01-16 15:20:05

回答

1

如果您需要检查重复项,您应该使用equals方法而不是hashCode。如果你读的Javadoc Object.hashCode,它说:

它不是必需的:如果两个对象根据equals不相等(java.lang.Object)方法,然后调用每个的hashCode方法两个对象必须产生不同的整数结果。

这意味着您可以有两个对象O1和O2具有相同的hashCode值,但其中o1.equals(o2) = false。你会发现一个虚假的重复。

要检查重复项,您可以使用Set,并检查每个添加的对象是否为Set.add(object) == true。如果它返回false,这意味着它已经在集合中。

在你的描述中,增量散列在我看来似乎是一个非常糟糕的散列函数,除非所有的对象都是同一个类,并且它们之间也有增量关系。例如,运行以下代码:

List l1 = Arrays.asList(1,2,3,4,5,6,7,8,9); 
    for (Object object : l1) { 
     System.out.println("hashCode: " + object.hashCode()); 
    } 

你不是说对象是你自己定义的类而不是。如果他们是您的,请务必记住,如果您覆盖equals,则应始终覆盖hashCode。如果没有,您违反了hashCode合同,并且某些类(如哈希集合)可能不像您预期​​的那样运行。

+0

我几乎同意所有的东西你说。但是,我不认为增量散列“非常糟糕”。没有冲突,并且根据所提供的有限信息,较低的位有所不同。很难想象这个哈希是如何为“随机”对象生成的。我的猜测是,对象不是随机的,即由于某种原因,集合有一堆连续的整数,或者更可能如OP和@Dave Newton指出的那样,节俭提供的散列码函数做了一些“不寻常”的事情。 – user949300 2012-01-16 17:18:31

+0

理论上,每个类都有定义散列码或使用超类的责任。 – 2012-01-16 17:33:27

+1

同意。节俭(或任何人)提供“散列码生成策略”的想法对我来说是新闻,并且有些令人不安。 – user949300 2012-01-16 18:21:17

1

有没有理由或常见的情况下,一个对象流将增量增加hashCodes?也许如果过去有人看到过这种现象,它可能会帮助我阐明我想了解的二进制文件。

简短的回答是它很有趣,但肯定没有错。该对象的类正在生成hashCode() - 这与序列化无关,除非由于某种原因哈希代码值已在对象构建期间计算出来,其中变得更奇怪。

您必须记住,散列码通常与mod函数一起使用,以将值放入散列桶中。只要由hashCode()方法返回的值服从的规格,它是好的:

  • hashCode方法必须一致地返回针对同一对象值相同的整数,没有提供用于在equals比较的对象是信息修改
  • 如果两个对象根据equals(Object)方法相等,则对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果
  • 程序员应该知道为不相等的整数产生结果对象可以提高散列表的性能。

它可能是它正在使用某种数据库ID生成的并且是故意单调递增的。或者这是某种Hadoop模式来跟踪独特的结果或其他内容。

1

他们可能是一个数字序列?

查看Integer和Long的代码,它们的哈希码本质上就是这个数字,连续的数字几乎都有连续的哈希码。

请注意,Long只会连续到Integer.MAX_VALUE,之后它不是连续的,尽管图案很好。

+0

哈!我将不得不检查 – jayunit100 2012-01-20 03:39:58