java 散列码中的桶_Java库谜题58:产生它的散列码

9624d0e4765450f79901e6cae0c45055.png

本谜题试图从前一个谜题中吸取教训。下面的程序还是由一个Name类和一个main方法构成,这个main方法还是将一个名字放置到一个散列集合中,然后检查该集合是否包含了这个名字。然而,这一次Name类已经覆写了hashCode方法。那么下面的程序将打印出什么呢?

import java.util.*;

public class Name {

private String first, last;

public Name(String first, String last) {

this.first = first; this.last = last;

}

public boolean equals(Name n) {

return n.first.equals(first) && n.last.equals(last);

}

public int hashCode() {

return 31 * first.hashCode() + last.hashCode();

}

public static void main(String[ ] args) {

Set s = new HashSet();

s.add(new Name("Donald", "Duck"));

System.out.println(

s.contains(new Name("Donald", "Duck")));

}

}

与谜题57一样,该程序的main方法创建了两个Name实例,它们表示的是相同的名字。这一次使用的名字是Donald Duck而不是Mickey Mouse,但是它们不应该有很大的区别。main方法同样还是将第一个实例置于一个散列集合中,然后检查该集合中是否包含了第二个实例。这一次hashCode方法明显是正确的,因此看起来该程序应该打印true。但是,表象再次欺骗了我们:它总是打印出false。这一次又是哪里出错了呢?

这个程序的缺陷与谜题57中的缺陷很相似,在谜题57中,Name覆写了equals方法,但是没有覆写hashCode方法;而在本谜题中,Name覆写了hashCode方法,但是没有覆写equals方法。这并不是说Name没有声明一个equals方法,它确实声明了,但是那是个错误的声明。Name类声明了一个参数类型是Name而不是Object的equals方法。这个类的作者可能想要覆写equals方法,但是却错误地重载了它[JLS 8.4.8.1, 8.4.9]。

HashSet类是使用equals(Object)方法来测试元素的相等性的;Name类中声明一个equals(Name)方法对HashSet不造成任何影响。那么Name是从哪里得到了它的equals(Object)方法的呢?它是从Object哪里继承而来的。这个方法只有在它的参数与在其上调用该方法的对象完全相同时才返回true。我们的程序中的main方法将一个Name实例插入到了散列集合中,并且测试另一个实例是否存在于该散列集合中,由此可知该测试一定是返回false的。对我们而言,两个实例可以代表那令人惊奇的水禽唐老鸭,但是对散列映射表而言,它们只是两个不相等的对象。

2829f2ca24f0d0090cbba57f30759f23.png

Java库谜题58:产生它的散列码.doc

下载Word文档到电脑,方便收藏和打印[全文共1066字]

编辑推荐:

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

下载Word文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值