在对象集合中递增的哈希码

时间:2012-01-16 15:12:07

标签: java collections hashcode

嗨伙计们:我正在尝试扫描一些物体,看看是否有任何重复。为此,我使用hashCode字段。对象在二进制文件中序列化。

看起来像这样:

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

我永远不会期望来自集合的hashCodes会展示这样的模式,除非JVM或thrift动态地为某些对象创建hashCodes,在某些情况下(或者,内部创建的每个对象都有一个设置为a的hashCode)静态递增的值)。

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

  • 次要细节:这些对象使用Apache thrift库进行二进制序列化,并且完全用java / hadoop读取/写入。

3 个答案:

答案 0 :(得分:1)

如果您需要检查重复项,则应使用equals方法而不是hashCode。如果您阅读了Object.hashCode的javadoc,它会说:

  

如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须产生不同的整数结果。

这意味着你可以拥有两个具有相同hashCode值的对象o1和o2,但是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合同,某些类(如散列集合)可能不会像您期望的那样运行。

答案 1 :(得分:1)

  

是否存在一个原因或一个常见情况,即对象流会逐渐增加hashCodes?也许如果有人在过去看到过这样的现象,它可能会帮助我揭示我想要理解的二进制文件。

简短的回答是它很有趣,但肯定没有错。有问题的对象的类是生成hashCode() - 它与序列化无关,除非由于某种原因在对象构造期间计算了哈希码值,更奇怪。

您必须记住,哈希码通常与mod函数一起使用,以将值放入哈希桶中。只要hashCode()方法返回的值符合规范,就可以了:

  • hashCode方法必须始终为同一对象值返回相同的整数,前提是没有在对象的equals比较中使用的信息被修改
  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果
  • 程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。

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

答案 2 :(得分:1)

他们可能是一系列数字吗?

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

请注意,Long只会连续到Integer.MAX_VALUE,之后它不是连续的,但仍有良好的图案。