2015-03-31 67 views
0

这段代码是否可以用hashCode作为一个简单的增量,以负数开始?将散列码作为简单增量可以吗?

private volatile static AtomicInteger creations = new AtomicInteger(Integer.MIN_VALUE); 
private final int creation; 

{ 
    creation = creations.getAndIncrement(); 
} 

@Override 
public int hashCode() { 
    return creation; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    if (creation == ((Stuff) obj).creation) 
     return true; 
    else 
     return false; 
} 

哈希码通常是用素数编码而不是简单增量? (之所以我希望它是这样的,是因为我用这个类创建的每个对象都是唯一的,我希望能够稍后将它从HashMap中移除,即使对象的状态将改变,因为它是我的理解哈希是否发生变化,然后在添加哈希映射后无法将其从哈希映射中移除)为了防止这种情况成为简单的是或否,请向我解释执行哈希的优点和缺点。

+0

“哈希码通常是用素数编码的,而不是用简单的增量?首先,我不认为哈希码通常是素数;散列**表**通常具有素数作为大小,但这是完全不同的事情。其次,使用一个简单的增量在你的情况下工作,因为你只有一个字段,并且该字段恰好是增量。但这是一个非常不寻常的情况。在大多数现实生活中,使用递增的值作为哈希代码是一个很大的失败,除非没有两个不同的对象是相等的,然后增量是毫无意义的。 – ajb 2015-03-31 06:52:09

+0

@ajb我之所以不希望两个对象具有相同的散列,以及为什么我希望以这种方式计算散列,是因为在HashMap中,如果哈希已更改,我无法删除它。所以基本上,这使得我无法为基于状态的哈希创建我的对象,这些对象是不断变化的状态。 – CodeCamper 2015-03-31 06:55:55

+0

好的,那就是_your_用例。但是如果你问为什么散列码通常不是使用一个简单的增量来计算的,那是因为你的用例不是典型的。而这种方法在元素放入哈希表的典型情况下不起作用。 – ajb 2015-03-31 07:01:26

回答

2

一般来说,这并不好。 object1.equals(object2)返回true的两个对象必须具有相同的hashCode

但是,在您的特定情况下,如果对象相等的唯一标准是创建属性,该属性与hashCode中使用的属性相同,则您的hashCode没问题。

然而,你hashCodeequals没有提供多少好处超过Object的默认实现,因为a.equals(b)为真当且仅当a==b

+1

我认为他们做... – assylias 2015-03-31 06:44:55

+0

@assylias我只是在发布我的答案后才读取OP的equals方法。现在编辑答案。 – Eran 2015-03-31 06:47:09

+0

我觉得标题很混乱。如果你只读了标题,答案通常是“否”。 – ajb 2015-03-31 06:48:40

2

是的没关系(如果两个实例是相等的,它们具有相同的哈希码),尽管您的equals/hashcode实现与Object的默认实现没有太大关系,所以没有必要这么做 - 除非您希望对象等于每2^32个实例创建。

根据你的补充,我将与帕特里夏沙纳汉的建议,同意使用identityHashCode

@Override 
public int hashCode() { 
    return System.identityHashCode(this); 
} 

@Override 
public boolean equals(Object obj) { 
return this == obj; 
} 

这本质上是在默认情况下所做的对象。就碰撞而言,我怀疑你会比你的碰撞有更多的碰撞。

+0

由于某种原因,我没有想到这个......所以它真的会产生与默认实现相同的结果?目前,我正在和班上一起压倒课程。有没有一种方法可以恢复默认实现,或者是我实现它的方式,几乎是实现这一目标的最佳方式? – CodeCamper 2015-03-31 06:46:27

+1

@CodeCamper只需删除这两个方法,你就会继承Object的默认实现。 – assylias 2015-03-31 06:47:10

+0

对于这个特殊的例子,我扩展了一个不是我的代码的类。我是否应该将源代码复制并粘贴到我自己的类中,并删除这两个方法,因为现在扩展该类保持对我来说很好和干净,我想无法以这种方式从子类中删除方法。另外,如何避免对象每2^32实例创建都相等,因为不是HashCode限制为Integer?起初,我希望HashCode能够很长时间,直到我意识到这是设计中的整数。 – CodeCamper 2015-03-31 06:49:24

相关问题