由于重复键会覆盖前一个键及其在hashmap中的相应值。但是如果我调用get()方法并将前一个键作为参数提供,它将返回overriden值。怎么可能,因为该键被新键覆盖,所以它应该抛出异常。
//This class is used as a key
Class MapKey
{
public boolean equlas( Object o)
{
return true;
}
}
//This is test class
class MapTest
{
public static void main(String a[])
{
Map m=new Hashmap<Mapkey, String>();
MapKey mk1=new MapKey();
m.put(mk1,"one");
MapKey mk2=new MapKey();
m.put(mk2,"two");
MapKey mk3=new MapKey();
m.put(mk3,"three");
System.out.println(m.get(mk1));
System.out.println(m.get(mk2));
}
}
输出:三 3
因为键是相等的所以它应该被最后一个键对象mk3覆盖。 那么如何用第一个或第二个关键对象检索值呢?
提前致谢
答案 0 :(得分:2)
这是因为您没有覆盖hashcode方法。在equals方法中,您已声明所有对象都相等。但由于默认的哈希码实现,所有相等的对象都返回不同的哈希码。由于哈希码用于在散列映射中保存值,因此您可以获取旧密钥mk1和mk2的值。
答案 1 :(得分:1)
equals
方法不是HashMap
最重要的方法。顾名思义,将值插入HashMap
的最重要方法是hashCode
,而不是equals
。如果映射中的键HashMap
满足以下条件,则k
中的值仅被覆盖:k.hashCode()
等于用于插入项的键的hashCode,键等于{ {1}}。
答案 2 :(得分:1)
您发布的代码没有提出
three
three
即使我修复它来清理编译错误:
import java.util.*;
class MapKey
{
public boolean equlas( Object o)
{
return true;
}
}
class MapTest
{
public static void main(String a[])
{
Map<MapKey, String> m=new HashMap<MapKey, String>();
MapKey mk1=new MapKey();
m.put(mk1,"one");
MapKey mk2=new MapKey();
m.put(mk2,"two");
MapKey mk3=new MapKey();
m.put(mk3,"three");
System.out.println(m.get(mk1));
System.out.println(m.get(mk2));
}
}
打印
one
two
即使我修复了MapKey来覆盖equals:
class MapKey
{
public boolean equlas( Object o)
{
return true;
}
public boolean equals( Object o)
{
return true;
}
}
打印相同的输出。
如果我实现hashCode:
class MapKey
{
public int hashCode()
{
return 1;
}
public boolean equals( Object o)
{
return true;
}
}
然后它会打印出来
three
three
hashCode和equals的默认实现基于对象引用,对不同对象的引用将不相等。地图使用hashCode来决定存储对象的存储桶,并使用equals来区分同一存储桶中的不同对象。
这里你创建了三个不同的实例,因此它们的hashCodes将是不同的(只要没有碰撞,在这种情况下将调用equals方法来决定两个对象是否相同)。在这种情况下,没有碰撞,并且直到hashCode被覆盖,不同的mapKey实例被视为等效。