【发布时间】:2017-06-15 10:45:10
【问题描述】:
我编写了一个代码,其中有学生类和学生对象用作键 如下,
public class ExampleMain01 {
private static class Student{
private int studentId;
private String studentName;
Student(int studentId,String studentName){
this.studentId = studentId;
this.studentName = studentName;
}
@Override
public int hashCode(){
return this.studentId * 31;
}
@Override
public boolean equals(Object obj){
boolean flag = false;
Student st = (Student) obj;
if(st.hashCode() == this.hashCode()){
flag = true;
}
return flag;
}
@Override
public String toString(){
StringBuffer strb = new StringBuffer();
strb.append("HASHCODE ").append(this.hashCode())
.append(", ID ").append(this.studentId)
.append(", NAME ").append(this.studentName);
return strb.toString();
}
public int getStudentId() {
return studentId;
}
public String getStudentName() {
return studentName;
}
} // end of class Student
private static void example02() throws Exception{
Set<Student> studentSet = new HashSet<Student>();
studentSet.add(new Student(12, "Arnold"));
studentSet.add(new Student(12, "Sam"));
studentSet.add(new Student(12, "Jupiter"));
studentSet.add(new Student(12, "Kaizam"));
studentSet.add(new Student(12, "Leny"));
for(Student s : studentSet){
System.out.println(s);
}
} // end of method example02
private static void example03() throws Exception{
Map<Student, Integer> map = new HashMap<Student,Integer>();
Student[] students = new Student [] {
new Student(12, "Arnold"),
new Student(12, "Jimmy"),
new Student(12, "Dan"),
new Student(12, "Kim"),
new Student(12, "Ubzil")
};
map.put(students[0], new Integer(23));
map.put(students[1], new Integer(123));
map.put(students[2], new Integer(13));
map.put(students[3], new Integer(25));
map.put(students[4], new Integer(2));
Set<Map.Entry<Student, Integer>> entrySet = map.entrySet();
for(Iterator<Map.Entry<Student, Integer>> itr = entrySet.iterator(); itr.hasNext(); ){
Map.Entry<Student, Integer> entry = itr.next();
StringBuffer strb = new StringBuffer();
strb.append("Key : [ ").append(entry.getKey()).append(" ], Value : [ ").append(entry.getValue()).append(" ] ");
System.out.println(strb.toString());
}
} // end of method example03
public static void main(String[] args) {
try{
example02();
example03();
}catch(Exception e){
e.printStackTrace();
}
}// end of main method
} // end of class ExampleMain01
在Student类的上述代码中,hashcode和equals的实现如下,
@Override
public int hashCode(){
return this.studentId * 31;
}
@Override
public boolean equals(Object obj){
boolean flag = false;
Student st = (Student) obj;
if(st.hashCode() == this.hashCode()){
flag = true;
}
return flag;
}
现在当我编译并运行代码时,
方法 example02 中的代码给出的输出为
HASHCODE 372, ID 12, NAME Arnold
即 Set 只包含一个对象,
我的理解是,由于所有对象的键具有相同的哈希码,因此只有一个对象位于存储桶 372 中。我说的对吗?
方法 example03() 也给出输出为
Key : [ HASHCODE 372, ID 12, NAME Arnold ], Value : [ 2 ]
从上面的方法我们可以看出,由于key返回的hashcode相同, Hashmap 只保存单个键值对。
所以我的问题是碰撞发生在哪里?
一个键可以指向多个值吗?
在搜索相应键的值时,链表的概念从何而来?
有人可以就我分享的例子向我解释上述内容吗?
【问题讨论】:
-
哈希冲突不是问题,您的问题是您提供了相同的 ID,并且您只在
equals方法中检查。