Java 将对象放入基于哈希的集合

Java 将对象放入基于哈希的集合,java,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.o

假设我有下面的班级

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,这也是正确的。但是如果我们注释equals并保留hashCode,它应该返回2,对吗?相反,它返回3。将对象放入hashmap时,map将检查对象的哈希代码,如果相同,它将替换映射的上一个值为新值,对吗


谢谢。

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

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

当您仅覆盖
hashcode
时,实际上没有任何变化。您只是将每个对象放在同一个桶中,返回222。因此,
HashMap
效率更低,但它的契约不会改变。

当您只覆盖
hashcode
时,实际上什么都不会改变。您只是将每个对象放在同一个桶中,返回222。因此,
HashMap
效率更低,但其契约没有改变

但是如果我们注释equals并保留hashCode,它应该返回2 正确的?相反,它返回3

3项是正确的行为。3个对象将散列到同一个bucket,但由于所有3个对象都不同,因此此bucket将包含一个值链(Java中HashMap的链表),具有相同的散列代码,但彼此不相等

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

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

但是如果我们注释equals并保留hashCode,它应该返回2 正确的?相反,它返回3

3项是正确的行为。3个对象将散列到同一个bucket,但由于所有3个对象都不同,因此此bucket将包含一个值链(Java中HashMap的链表),具有相同的散列代码,但彼此不相等

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


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

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

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


本质上,如果不实现合理的hashcode,您就是在转换列表中的hashcontainer(以及低效的hashcontainer)。

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

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

本质上,如果不实现合理的hashcode,您就是在转换列表中的hashcontainer(以及效率低下的容器)

如果我们注释hashCode(),它将返回3,这也是正确的

这是不对的!只有两个不同的对象:“a”和“b”。equals方法表示什么是相等的,什么是不相等的。预期大小为2。但是,因为equals hashcode契约被破坏,所以返回的大小是3

如果我们注释hashCode(),它将返回3,这也是正确的

这是不对的!只有两个不同的对象:“a”和“b”。equals方法表示什么是相等的,什么是不相等的。预期大小为2。但是,因为equals hashcode契约被破坏,所以返回的大小是3