检索hashmap中的重复键

时间:2015-04-14 18:50:57

标签: java

由于重复键会覆盖前一个键及其在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覆盖。 那么如何用第一个或第二个关键对象检索值呢?

提前致谢

3 个答案:

答案 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实例被视为等效。