你好我正在攻读OCP考试,我对哈希图有疑问。在这里,我已经用(thirdStudent,“3”)替换了我的第一个键值(firstStudent,“1”)
package hashmapexam;
import java.util.HashMap;
import java.util.Map;
public class HashMapExam {
public static void main(String[] args) {
Student firstStudent = new Student("Rob");
Student secondStudent = new Student("Catlin");
Student thirdStudent = new Student("Rob");
Map <Student,String> students = new HashMap<>();
students.put(firstStudent, "1");
students.put(secondStudent, "2");
students.put(thirdStudent, "3");
System.out.println("Size of the Map : " + students.size());
System.out.println(students.get(firstStudent));
System.out.println(students.get(secondStudent));
System.out.println(students.get(thirdStudent));
}
}
package hashmapexam;
class Student{
String name;
public Student(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public boolean equals(Object o){
if(o instanceof Student && ((Student)o).getName().equals(this.getName())){
return true;
}
else{
return false;
}
}
@Override
public int hashCode(){
return name.length();
}
}
我得到以下输出
地图的大小:2
3
2
3
似乎它们已被正确替换,因为地图的大小是2.但是如何使用firstStudent和thirdStudent Keys检索值“3”?没有firstStudent键被第三学生取代?
答案 0 :(得分:2)
firstStudent
和thirdStudent
是equal
。这意味着您可以使用任一引用作为键来获取相应的值。
顺便说一句,使用length
的{{1}}对于String
方法来说不是一个好主意,因为它会导致许多不同的通用名称具有相同的hashCode
}。最好使用hashCode
的{{1}}。
答案 1 :(得分:1)
因为哈希映射(如名称所示)使用键的哈希值将值放入其桶中。在您的情况下,您的Student
类实现了equals
和hashcode
方法,其中firstStudent
和thirdStudent
都返回相同的哈希值;因此,您的地图中有2个值,并且检索(firstStudent
或thirdStudent
)将返回相同的值; 3
,因为thirdStudent
替换1
设置的值firstStudent
,因为它们都具有相同的哈希值(编辑)并且被视为相等
students.put(firstStudent, "1");
// map size: 1
students.put(secondStudent, "2");
// map size: 2
students.put(thirdStudent, "3");
// map size: 2 (replaced first inserted value)
本质上
boolean b = students.get(firstStudent).equals(students.get(thirdStudent));
// b==true since firstStudent.equals(thirdStudent)==true
答案 2 :(得分:1)
您的equals()
方法表示具有相同Student
的任何name
实例都相同。 HashMap
在其操作中使用此相等,所以
students.put(thirdStudent, "3");
将替换
创建的条目students.put(firstStudent, "1");
thirdStudent
和firstStudent
是等效键。
同样,students.get(firstStudent)
和students.get(thirdStudent)
返回相同的值,因为使用的密钥是等效的。
(当然,对于散列数据结构,这依赖于hashCode
的正确实现。)
另一个例子:
new Integer(1) != new Integer(1)
(new Integer(1)).equals(new Integer(1))
(new Integer(1)).hashcode() == (new Integer(1)).hashcode()
这就是为什么Integer
可以用作HashMap
s中的键的原因。
答案 3 :(得分:1)
您的Student
firstStudent
和thirdStudent
对象相等且 hashCode 也会返回相同的值,即3因为覆盖学生班中的hashCode
,实习生返回字符串的长度,即
@Override
public int hashCode(){
return name.length();
}
答案 4 :(得分:1)
:
如果地图以前包含该键的映射,则为旧值 由指定的值替换。 据说地图m包含一个 当且仅当map.containsKey(key)返回时才映射键k 真正。当且仅当此映射包含键k的映射使得key == null时,map.containsKey(key)才返回true。 k == null:key.equals(k)
在你的情况下,你首先添加&#34; firstStudent&#34;有价值&#34; 1&#34;而且你已经添加了&#34; thirdStudent&#34;但作为thirdStudent.equals(firstStudent),firstStudent的值将被&#34; 3&#34;
取代 在hashmap的get方法中:
返回指定键映射到的值,如果是,则返回null 此映射不包含键的映射。更正式的是, 如果这样的话 map包含从键k到值v的映射,使得(key == null ? k == null:key.equals(k)),然后此方法返回v;否则它 返回null。
在您的情况下,firstStudent和thirdStudent引用相同的值
答案 5 :(得分:0)
students.put(firstStudent,“1”);
地图: Rob - &gt; 1 强>
students.put(secondStudent, "2");
地图: Rob - &gt; 1 和 Catlin - &gt; 2 强>
students.put(thirdStudent, "3");
地图: Rob - &gt; 3 (第三名学生也被命名为'Rob') Catlin - &gt; 2 强>
因此,如果您使用'Rob'访问Map,则获得'3',因为第二个Put使用'Rob'将值'1'替换为'3'。自从第一次和 第三个学生都被称为'Rob',equals只按名称进行比较,两者都有相同的哈希码,从HashMap的角度看它们是相同的键。 因此,在三次“放置”操作后,地图只包含两个条目。
所以你得到Rob - &gt; 3 Catlin - &gt; 2 Rob - &gt; 3 ...序列3,2,3
答案 6 :(得分:0)
错误:href="#{{ loc }}"
和firstStudent
是同一个对象。
&#34;同样的&#34;意味着它们在java方面是相同的。
原因:内容相同的字符串与您的学生相同 被称为&#34;抢&#34;。
您的hashMap将两个学生放在同一个桶中,因为名称(=键)相等,因此两者都为您提供输出thirdStudent