【发布时间】:2017-08-30 18:35:04
【问题描述】:
我已阅读有关 Hashmap 冲突的信息并举了以下示例。由于我无法理解什么是碰撞以及如何避免发生碰撞。示例如下
import java.util.*;
class JavaCollision{
public static void main(String args[]){
HashMap<Person, String> map=new HashMap<Person, String>();
Person p1 = new Person(1,"ABC");
Person p2 = new Person(2,"DEF");
Person p3 = new Person(1,"XYZ");
Person p4 = new Person(1,"PQR");
Person p5 = new Person(1,"PQR");
System.out.println("Adding Entries ....");
map.put(p1,"ONE");
map.put(p2,"TWO");
map.put(p3,"THREE");
map.put(p4,"FOUR");
map.put(p5,"FIVE");
System.out.println("\nComplete Map entries \n" + map);
/* System.out.println("\nAccessing non-collided key");
System.out.println("Value = "+map.get(p2));
System.out.println("\nAccessing collided key");
System.out.println("Value = " + map.get(p1));*/
System.out.println("P1 hashcode is:"+map.get(p1).hashCode()+" And value is:"+map.get(p1));
System.out.println("P2 hashcode is:"+map.get(p2).hashCode()+" And value is:"+map.get(p2));
System.out.println("P3 hashcode is:"+map.get(p3).hashCode()+" And value is:"+map.get(p3));
System.out.println("P4 hashcode is:"+map.get(p4).hashCode()+" And value is:"+map.get(p4));
System.out.println("P5 hashcode is:"+map.get(p5).hashCode()+" And value is:"+map.get(p5));
}
}
Person.java
public class Person {
private int id;
private String name;
public Person(int id, String name) {
this.id = id; this.name = name;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setName (String name) {
this.name = name;
}
public int hashCode(){
System.out.println("Called hashcode for:"+id+" - "+name);
return id;
}
public boolean equals(Object obj){
System.out.println("Called equals on ="+id+" - "+name+" to compare with "+((Person)obj));
boolean result=false;
if(obj instanceof Person){
if( ((Person)obj).getId() == id && ((Person)obj).getName().equals(name) ){
result=true;
System.out.println("Result is true");
}
}
return result;
}
public String toString() {
return id+" . "+name;
}
}
结果是
Adding Entries ....
Called hashcode for:1 - ABC
Called hashcode for:2 - DEF
Called hashcode for:1 - XYZ
Called equals on =1 - XYZ to compare with 1 . ABC
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called equals on =1 - PQR to compare with 1 . PQR
Result is true
Complete Map entries
{1 . ABC=ONE, 1 . XYZ=THREE, 1 . PQR=FIVE, 2 . DEF=TWO}
Called hashcode for:1 - ABC
Called hashcode for:1 - ABC
P1 hashcode is:78406 And value is:ONE
Called hashcode for:2 - DEF
Called hashcode for:2 - DEF
P2 hashcode is:83500 And value is:TWO
Called hashcode for:1 - XYZ
Called equals on =1 - XYZ to compare with 1 . ABC
Called hashcode for:1 - XYZ
Called equals on =1 - XYZ to compare with 1 . ABC
P3 hashcode is:79801726 And value is:THREE
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
P4 hashcode is:2158258 And value is:FIVE
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called equals on =1 - PQR to compare with 1 . PQR
Result is true
Called hashcode for:1 - PQR
Called equals on =1 - PQR to compare with 1 . ABC
Called equals on =1 - PQR to compare with 1 . XYZ
Called equals on =1 - PQR to compare with 1 . PQR
Result is true
P5 hashcode is:2158258 And value is:FIVE
在这个结果中 p4 和 p5 具有相同的哈希码。如何避免在 hashmap 中使用相同的 hashcode。我们可以通过返回哈希码来避免冲突吗?
【问题讨论】:
-
如果你想避免冲突,请不要用不同的值散列相同的键。这就是你为
p4和p5做的事情。 -
使用一些返回唯一值的函数为您的对象生成哈希码。
-
感谢您的回复。所以这里 p4 和 p5 对象是碰撞的吧?
-
@Muthuvigneshk 正确。基本上
p5在这里替换了p4,这就是为什么你看到P4 hashcode is:2158258 And value is:FIVE而不是P4 hashcode is:2158258 And value is:FOUR -
您的代码没有意义:
System.out.println("P5 hashcode is:"+map.get(p5).hashCode()+" And value is:"+map.get(p5));您没有显示 p5 的哈希码。您正在显示与 p5 关联的 value 的哈希码,这意味着您正在显示"FIVE".hashCode()(与 HashMap 逻辑无关)。为了避免冲突,唯一的建议是构建一个更好的hashCode函数。如果你的equals()有name参与相等性检查,你应该在哈希码计算中包括name。
标签: java collections hashmap collision