散列表中以自己的类为键

为了在散列表中将自己的类作为键使用,必须同时覆盖hashCode()和equals()。
看一个例子:

package com.cqdxwjd.chapter8;

import java.util.Hashtable;

class Groundhog {
    int ghNumber;

    Groundhog(int n) {
        ghNumber = n;
    }
}

class Prediction {
    boolean shadow = Math.random() > 0.5;

    public String toString() {
        if (shadow)
            return "Six more weeks of Winter!";
        else
            return "Early Spring!";
    }
}

public class SpringDetector {
    public static void main(String[] args) {
        Hashtable ht = new Hashtable();
        for (int i = 0; i < 10; i++)
            ht.put(new Groundhog(i), new Prediction());
        System.out.println("ht = " + ht + "\n");
        System.out.println("Looking up prediction for groundhog #3:");
        Groundhog gh = new Groundhog(3);
        if (ht.containsKey(gh))
            System.out.println((Prediction) ht.get(gh));
    }
}

运行结果为:

ht = {com.cqdxwjd.chapter8.Groundhog@3219ab8d=Early Spring!, com.cqdxwjd.chapter8.Groundhog@1cf15b84=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog@65b1fd9c=Early Spring!, com.cqdxwjd.chapter8.Groundhog@334dcfad=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog@88140ed=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog@5dcd8bf7=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog@11b75be2=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog@5d0769dd=Early Spring!, com.cqdxwjd.chapter8.Groundhog@29af45f4=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog@61a0353d=Six more weeks of Winter!}

Looking up prediction for groundhog #3:

可以看到最后查找标号为3的Groundhog时,没有结果。因为Groundhog是从通用的Object根类继承的。事实上是用Object的hashCode()方法生成每个对象的散列码,而且默认情况下只使用它的对象地址。所以,Groundhog(3)的第一个实例并不会产生与
Groundhog(3)第二个实例相等的散列码,而我们用第二个实例进行检索。
大家或许认为此时要做的全部事情就是正确地覆盖hashCode()。但这样做依然行不能,除非再做另一件事情:覆盖也属于Object 一部分的equals()。当散列表试图判断我们的键是否等于表内的某个键时,就会用到这个方法。同样地,默认的Object.equals()只是简单地比较对象地址,所以一个Groundhog(3)并不等于另一个Groundhog(3)。因此,为了在散列表中将自己的类作为键使用,必须同时覆盖hashCode()和equals(),就象下面展示的那样:

package com.cqdxwjd.chapter8;

import java.util.Hashtable;

class Groundhog2 {
    int ghNumber;

    Groundhog2(int n) {
        ghNumber = n;
    }

    public int hashCode() {
        return ghNumber;
    }

    public boolean equals(Object o) {
        return (o instanceof Groundhog2)
                && (ghNumber == ((Groundhog2) o).ghNumber);
    }
}

class Prediction {
    boolean shadow = Math.random() > 0.5;

    public String toString() {
        if (shadow)
            return "Six more weeks of Winter!";
        else
            return "Early Spring!";
    }
}

public class SpringDetector2 {
    public static void main(String[] args) {
        Hashtable ht = new Hashtable();
        for (int i = 0; i < 10; i++)
            ht.put(new Groundhog2(i), new Prediction());
        System.out.println("ht = " + ht + "\n");
        System.out.println("Looking up prediction for groundhog #3:");
        Groundhog2 gh = new Groundhog2(3);
        if (ht.containsKey(gh))
            System.out.println((Prediction) ht.get(gh));
    }
}

运行结果为:

ht = {com.cqdxwjd.chapter8.Groundhog2@9=Early Spring!, com.cqdxwjd.chapter8.Groundhog2@8=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog2@7=Early Spring!, com.cqdxwjd.chapter8.Groundhog2@6=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog2@5=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog2@4=Early Spring!, com.cqdxwjd.chapter8.Groundhog2@3=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog2@2=Early Spring!, com.cqdxwjd.chapter8.Groundhog2@1=Six more weeks of Winter!, com.cqdxwjd.chapter8.Groundhog2@0=Six more weeks of Winter!}

Looking up prediction for groundhog #3:
Six more weeks of Winter!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值