java HashMap用自定义类做key(二)

解决自定义类作为HashMap Key的问题
本文讨论了如何在Java中使用自定义类作为HashMap的Key,遇到的问题在于类的hashCode和equals方法未正确实现导致无法覆盖相同Key的值。通过重载hashCode和equals方法解决了问题,并解释了为何String类能正确处理这种情况。

 由于设计的需要,要自己编写一个类,作为HashMap中的Key。先简单测试一下,三下五除二,写了个类,没想到不行。才知道自己又想当然了。下面是我的程序:
class Index{
   String ID="";
   public Index(String ID){
      this.ID=ID;
   }
   public String getID(){
      return ID;
   }
}
String str="123";
String str1=new String("123");
HashMap<Index,String> hm=new HashMap<Index,String>();
hm.put(new Index("123"), "lue");
hm.put(new Index("123"), "abcue");
hm.put(new Index(str), "alsfeue");
hm.put(new Index(str), "value");
hm.put(new Index(str1), "zzzzzzz");
System.out.println(hm.size());
System.out.println(hm.get(new Index("123")));

运行结果为:
5
null

结果让我很是失望。但原因其实很简单,就是这些Key的hashcode不同,因此不能把内容相同的key的value给覆盖掉。但如何解决呢?在网上找了一下,结果还真有这方面的内容,不过好像很少有人这么用。
原来是因为Index是继承Object的.使用Object的hashCode生成的散列码.它默认是使用对象的地址计算散列码的.因此.两次new的MyKey的散列码是不一样的.有人可能又问了,既然是用对象地址计算散列码,那么如果用String对象作为HashMap的Key,则不会出现这种情况,这是为什么呢?这是因为String类重载了hashCode函数。看来我也应该重新写我的类的hashCode函数了。
还有一个函数应该重载,就是equals函数,因为当比较两个类时,如果这个类中没有equals函数,则到它的上一级去找,而我的这个类是继承自Object类,则调用Object类的equals,结果是按照这两个对象的地址比较的,自然是不会相等的。

下面是修改后的类:

class Index{
    String ID="";
   public Index(String ID){
      this.ID=ID;
   }
   public String getID(){
      return ID;
   }
   public int hashCode(){
      return ID.hashCode();
   }
   public boolean equals(Object index){
      return (index instanceof Index) && (ID.equals(((Index)index).getID()));
   }
}
String str="123";
String str1=new String("123");//使str1和str地址不同
HashMap<Index,String> hm=new HashMap<Index,String>();
hm.put(new Index("123"), "lue");
hm.put(new Index("123"), "abcue");
hm.put(new Index(str), "alsfeue");
hm.put(new Index(str), "value");
hm.put(new Index(str1), "zzzzzzz");
System.out.println(hm.size());
System.out.println(hm.get(new Index("123")));

运行结果为:
1
zzzzzzz

搞定!

这其中涉及到了一个操作符:instanceof。下面做简要介绍:
instanceof 运算符是在运行期间测试一个对象的类型,运算符左边是一个对象的实例,而右边是一个类或接口的名字。如果左边的对象实例是属于右边的类或其子类的实例,或者是实现了接口类的实例则返回true。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值