Java 当我重写hashcode并从hashmap获取值时,为什么必须重写equals
当我只重写hashCode()函数和comment equalas()方法时,我会得到以下输出:Java 当我重写hashcode并从hashmap获取值时,为什么必须重写equals,java,hashmap,equals,hashcode,Java,Hashmap,Equals,Hashcode,当我只重写hashCode()函数和comment equalas()方法时,我会得到以下输出: public class DemoHashSet { private String name; private String dob; private String gender; public DemoHashSet(String name, String dob, String gender) { super(); this.name = name; this.dob
public class DemoHashSet {
private String name;
private String dob;
private String gender;
public DemoHashSet(String name, String dob, String gender) {
super();
this.name = name;
this.dob = dob;
this.gender = gender;
}
public String getName() {
return name;
}
public String getDob() {
return dob;
}
public String getGender() {
return gender;
}
@Override
public String toString() {
return name+" "+dob+" "+gender;
}
@Override
public boolean equals(Object o) {
return this.name.equals(((DemoHashSet)o).getName());
}
@Override
public int hashCode() {
int code = this.name.hashCode() + this.dob.hashCode() + gender.hashCode();
System.out.println("Hash Code: "+code);
return code;
}
public static void main(String args[]) throws ParseException {
Map<DemoHashSet, String> hmap = new HashMap<DemoHashSet, String>();
DemoHashSet obj1 = new DemoHashSet("key1", "121990", "male");
DemoHashSet obj2 = new DemoHashSet("key2", "122990", "male");
DemoHashSet obj3 = new DemoHashSet("key3", "123990", "male");
DemoHashSet obj4 = new DemoHashSet("key4", "124990", "male");
DemoHashSet obj5 = new DemoHashSet("key5", "125990", "male");
hmap.put(obj1, "value1");
hmap.put(obj2, "value2");
hmap.put(obj3, "value3");
hmap.put(obj4, "value4");
hmap.put(obj5, "value5");
System.out.println("Get values: ");
System.out.println(hmap.get(new DemoHashSet("key1", "121990", "male")));
System.out.println(hmap.get(new DemoHashSet("key2", "122990", "male")));
}
}
需要解释此行为,因为在两种情况下计算的哈希代码相同,但在第二种情况下,它给出null
hadCode()函数的作用是通过导出特定段/桶的对象键,将对象存储在特定段/桶中。要理解此方法的用途,您需要了解HashTable或HashMap在内部是如何工作的。维基百科是了解它的最佳来源
equals()函数用于检查集合对象中是否存在特定对象
如果两个对象相等,hasCode将相同,但反之则不正确。两个不同的对象可以具有相同的哈希代码
hadCode()函数的作用是通过导出特定段/桶的对象键,将对象存储在特定段/桶中。要理解此方法的用途,您需要了解HashTable或HashMap在内部是如何工作的。维基百科是了解它的最佳来源
equals()函数用于检查集合对象中是否存在特定对象
如果两个对象相等,hasCode将相同,但反之则不正确。两个不同的对象可以具有相同的哈希代码
需要对这种行为进行解释
这正是我所期望的行为。为什么?
hascode有一点是不能100%保证唯一对象的唯一性。这意味着在某些情况下 不同的对象可以有相似的hascode HashMap实现将这一点牢记在心。因此,当您传递一个键时,它们总是比较
hascode
,然后检查相等性(参考检查然后是equals()
方法)。如果未找到任何内容,则返回null
。您可以检查源代码:
Hash Code: 1457153183
Hash Code: 1457182975
Hash Code: 1457212767
Hash Code: 1457242559
Hash Code: 1457272351
Get values:
Hash Code: 1457153183
null
Hash Code: 1457182975
null
此代码块表示:
(hascode)对于给定的键和条目键都需要相同hash
- 给定的键和输入键需要是相同的对象(相同的引用)或它们需要通过
方法相等equals()
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
后来
DemoHashSet obj1 = new DemoHashSet("key1", "121990", "male");
不引用同一对象,因此equals()
return false和get()
returnnull
未找到与键匹配的项。当您的
equals()
方法根据您的实现而存在时,您告诉这些对象是相等的,因为它们具有相同的名称
哈希代码不能保证且不相等。需要解释此行为。
这正是我所期望的行为。为什么?
hascode有一点是不能100%保证唯一对象的唯一性。这意味着在某些情况下 不同的对象可以有相似的hascode HashMap实现将这一点牢记在心。因此,当您传递一个键时,它们总是比较
hascode
,然后检查相等性(参考检查然后是equals()
方法)。如果未找到任何内容,则返回null
。您可以检查源代码:
Hash Code: 1457153183
Hash Code: 1457182975
Hash Code: 1457212767
Hash Code: 1457242559
Hash Code: 1457272351
Get values:
Hash Code: 1457153183
null
Hash Code: 1457182975
null
此代码块表示:
(hascode)对于给定的键和条目键都需要相同hash
- 给定的键和输入键需要是相同的对象(相同的引用)或它们需要通过
方法相等equals()
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
后来
DemoHashSet obj1 = new DemoHashSet("key1", "121990", "male");
不引用同一对象,因此equals()
return false和get()
returnnull
未找到与键匹配的项。当您的
equals()
方法根据您的实现而存在时,您告诉这些对象是相等的,因为它们具有相同的名称
hashcode不能保证并且不是相等的。您使用的是
HashMap
。在内部,HashMap
有许多bucket,每个bucket都有一个存储项的列表
无论何时调用HashMap.get()
,HashMap
都将调用DemoHashSet.hashCode()
,并使用键参数(可能带有模数(%
)运算符)来确定要查找的存储桶
然后,它将使用DemoHashSet.equals()
方法搜索此列表,查看它是否可以匹配键参数。如果它equals()
曾经返回true
,则将返回该值,否则返回null
从以下文件中:
注意,通常需要重写hashCode方法
每当重写此方法时,以保持
hashCode方法的契约,它声明必须有相等的对象
具有相等的散列码
您正在使用一个
HashMap
。在内部,HashMap
有许多bucket,每个bucket都有一个存储项的列表
无论何时调用HashMap.get()
,HashMap
都将调用DemoHashSet.hashCode()
,并使用键参数(可能带有模数(%
)运算符)来确定要查找的存储桶
然后,它将使用DemoHashSet.equals()
方法搜索此列表,查看它是否可以匹配键参数。如果它equals()
曾经返回true
,则将返回该值,否则null<