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