将对象放入基于散列的集合

时间:2011-08-31 10:59:14

标签: java

假设我有以下课程。

class S{

String txt = null;

S(String i){
txt=i;
}

public static void main(String args []){
S s1 = new S("a");
S s2 = new S("b");
S s3 = new S("a"); 

Map m = new HashMap ();
m.put(s1, "v11");
m.put(s2, "v22");
m.put(s3, "v33");

System.out.println(m.size());   
}

//just a plain implementation
 public boolean equals(Object o)
 {
      S cc = (S) o;
      if (this.i.equals(cc.i))
      {    
         return true;
      }
      else
      {
         return false;
      }    
   }

   public int hashCode()
   {
      return 222;
   }  

}

在上面运行时,这将返回2的大小。它完全没问题。如果我们注释hashCode()它返回3也是正确的。但是如果我们评论等于并保持hashCode它应该返回2对吗?而将它返回3.当将对象放到hashmap map时会检查一个对象的哈希码,如果它相同,它会将地图的先前值替换为新的一个吗?

谢谢。

5 个答案:

答案 0 :(得分:2)

  

但是如果我们评论等于并保持hashCode它应该返回2   对?相反,它返回3.

3项是正确的行为。 3个对象将被散列到同一个存储桶,但由于所有3个存在不同,因此该存储桶将包含一组值(Java中的HashMap的链表),具有相同的哈希码但不相等。

  

将对象放入hashmap map时,将检查对象的哈希码以及是否相同   它会将地图的先前值替换为新的权利吗?

如果将它们散列到同一个桶中,并不意味着一个值将替换另一个值。然后将比较这些值的相等性。如果它们相等,那么旧的值将被替换,如果它们不是 - 新的值将被添加到链表的尾部(对于这个桶)。

答案 1 :(得分:1)

哈希码仅用于确定放置对象的存储区。每个桶可以包含多个对象。因此必须实现哈希码以确保相同的对象进入同一个桶。换句话说,相等的对象必须具有相同的哈希码,但具有相同哈希码的对象不一定相等。

答案 2 :(得分:1)

当您仅覆盖hashcode时,没有任何真正的变化。您只是将每个对象放在return 222的同一个存储桶中。所以HashMap效率更低,但合同不会改变。

答案 3 :(得分:0)

哈希码是第一个快速查找两个对象是否相等的方法。散列容器使用它来决定对象可以进入哪个“槽”,并在不检查所有槽中的所有对象的情况下检索它。

如果您的哈希码始终相同,则所有对象都将定向到同一个槽。这称为碰撞。插入速度会变慢,因为在碰撞之后,容器必须检查该插槽中已有的对象是否与新的对象匹配(equals)。此外,检索将更慢,因为它必须按顺序检查它们,直到找到正确的(equals againg)。最后,可能会有大量未使用的内存浪费在不会使用的插槽中。

实质上,通过不实现合理的哈希码,您将转换列表中的哈希容器(以及效率低下的哈希容器)。

答案 4 :(得分:0)

  

如果我们评论hashCode(),它返回3也是正确的。

这不对!只有2个不同的对象:“a”和“b”。 equals方法表示什么是平等的,什么不是。预期大小为2.但是,由于equals-hashcode合约被破坏,返回的大小为3。