使用对象作为hashMap的键,需要覆盖hashcode和equals方法
1:HashMap可以存放键值对,如果要以对象(自己创建的类等)作为键,实际上是以对象的散列值(以hashCode方法计算得到)作为键。hashCode计算的hash值默认是对象的地址值。
这样就会忽略对象的内容,不是以对象的内容来判断。如果要以对象的内容进行判断,就要覆盖掉对象原有的hashCode方法。
另外HashMap是以equals方法判断当前的键是否与表中存在的键是否相同,所以覆盖hashCode方法之后,还不能正常运行。还要覆盖equals方法
先判断hash(hash函数)值是否相同,相同了说明某个位置上有多个元素,再用equals(线性查找)方法判断。
来看下面一个天气预报系统的例子:
2:创建一个作为HashMap的键的对象Groundhog(土拔鼠)与Prediction(预报)对象联系起来,
package chapter17.nine;
public class Groundhog {
protected int number;
public Groundhog(int n) {
// TODO Auto-generated constructor stub
number=n;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "Groundhog #"+number;
}
}
package chapter17.nine;
import java.util.Random;
public class Prediction {
private static Random random=new Random(); //传递进参数,创建的随机数将会相同
private boolean shadow=random.nextDouble()>0.5;
@Override
public String toString() {
// TODO Auto-generated method stub
if(shadow){
return "Six more weeks of Winter!";
}else{
return "Early Spring";
}
}
}
3:创建一个测试类
public class SpringDetector {
public static <T extends Groundhog> void detectSpring(Class<T> type) throws Exception, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Constructor<T> ghog=type.getConstructor(int.class); //含有int参数的构造函数
Map<Groundhog, Prediction> map=new HashMap<Groundhog, Prediction>();
for (int i = 0; i < 10; i++) {
map.put(ghog.newInstance(i), new Prediction());
}
System.out.println("map="+map);
Groundhog gh=ghog.newInstance(3);
System.out.println("Looking up prediction for "+gh);
if(map.containsKey(gh)){ //map是根据对象生成的hascode地址判断对象是否相同的,
//如果想让对象作为map的键,来判断对象是否相同。那么对象应该覆盖hashcode和equals方法。生成对象自己的hashcode吗。
//例如按照对象包含的int属性生成hashcode 吗等。HashMap使用equals判断当前的键是否与表中存在的键相同。所以要覆盖equals方法
System.out.println(map.get(gh));
}else{
System.out.println("Key not found"+gh);
}
}
public static void main(String[] args) {
try {
detectSpring(Groundhog.class);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试结果:
map={Groundhog #1=Six more weeks of Winter!, Groundhog #4=Six more weeks of Winter!, Groundhog #5=Six more weeks of Winter!, Groundhog #3=Early Spring, Groundhog #8=Six more weeks of Winter!, Groundhog #7=Six more weeks of Winter!, Groundhog #0=Early Spring, Groundhog #2=Early Spring, Groundhog #9=Six more weeks of Winter!, Groundhog #6=Early Spring}
Looking up prediction for Groundhog #3
Key not foundGroundhog #3
我们发现,map中并不包含Groundhog gh=ghog.newInstance(3);的键,可是实际上map中又添加了ghog.newInstance(3)的键。这是为什么呢?
因为实际上判断的对象的hash值。所有造成:第一个ghog.newInstance(3)的hash值不等于第二个ghog.newInstance(3)的hash值;
4:重写Groundhog并覆盖hashCode方法和equals方法
package chapter17.nine;
public class Groundhog2 extends Groundhog{
public Groundhog2(int n) {
super(n);
// TODO Auto-generated constructor stub
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return number;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return obj instanceof Groundhog2 && number==((Groundhog2)obj).number;
}
}
5:测试。
package chapter17.nine;
import java.lang.reflect.InvocationTargetException;
public class SpringDetector2 {
public static void main(String[] args) {
try {
SpringDetector.detectSpring(Groundhog2.class);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6:测试结果。
map={Groundhog #0=Six more weeks of Winter!, Groundhog #1=Early Spring, Groundhog #2=Early Spring, Groundhog #3=Early Spring, Groundhog #4=Early Spring, Groundhog #5=Six more weeks of Winter!, Groundhog #6=Early Spring, Groundhog #7=Early Spring, Groundhog #8=Early Spring, Groundhog #9=Six more weeks of Winter!}
Looking up prediction for Groundhog #3
Early Spring
第一个ghog.newInstance(3)的hash值等于第二个ghog.newInstance(3)的hash值。定义作为HashMap键的对象成功。
使用对象作为hashMap的键,需要覆盖hashcode和equals方法的更多相关文章
- 何时覆盖hashCode()和equals()方法
The theory (for the language lawyers and the mathematically inclined): equals() (javadoc) must defin ...
- 当我们用自定义的类对象作为key时,我们必须在程序中覆盖HashCode()和equals()。
Key值既然可以作为对象,那么也可以用一个自定义的类.比如: m.put(new sutdent(“Liucy”,30),”boss”) 如果没有语句来判定Student类对象是否相同,则会全部打印出 ...
- HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法
之前一直不是很理解为什么要重写HashCode和Equals方法,才只能作为键值存储在HashMap中.通过下文,可以一探究竟. 首先,如果我们直接用以下的Person类作为键,存入HashMap中, ...
- 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- (转)为什么要重写 hashcode 和 equals 方法?
作者丨hsm_computer cnblogs.com/JavaArchitect/p/10474448.html 我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候 ...
- 为什么要重写hashcode和equals方法
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- 重写hashcode和equals方法
重写hashcode和equals方法 简乐君 2019-05-07 21:55:43 35481 收藏 191分类专栏: Java 文章标签: equals() hashcode()版权 一.前言我 ...
- JAVA中的各种 哈希码(HashCode) 与 equals方法在HIBERNATE的实际应用[转载]
1.什么是哈希码(HashCode) 在Java中,哈希码代表对象的特征.例如对象 Java代码 String str1 = “aa”, str1.hashCode= 3104 String str2 ...
- K:java中的hashCode和equals方法
hashCode和equals方法是Object类的相关方法,而所有的类都是直接或间接的继承于Object类而存在的,为此,所有的类中都存在着hashCode和equals.通过翻看Object类 ...
随机推荐
- 安装ahci驱动后出现A disk read error occurred如何解决
注意:因为一般的ghost系统盘都没有ahci驱动,所以,如果用到固态硬盘且想更好的发挥固态硬盘的性能,需要安装ahci驱动,且在bios 中把硬盘模式设置成ahci(否则电脑会蓝屏或进不去系统) 步 ...
- 【转】VC 隐藏模块、MFC 改变窗口类名
[转]VC 隐藏模块 void HideDll() { HMODULE hMod = ::GetModuleHandle("MyHook.dll"); PLIST_ENTRY He ...
- 【laravel5.6】laravel 自定义公共函数
1.在 app/Helpers/ 新建一个文件 functions.php,当然这个文件位置和名称你可以自己定义,创建一些函数用于全局调用: 2.在composer.json中的autoload下增加 ...
- Delphi XE 10 跨平台三层数据库应用教程
Delphi XE 10 跨平台三层数据库应用教程 前言: Delphi XE 开始越来越庞大,比经典的Delphi7难用,但依然是目前所有跨平台开发工具中开发效率最高.最容易上手的,其快速设计RAD ...
- LeetCode-494. Target Sum(DFS&DP)
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...
- junit4 详解
转:http://www.cnblogs.com/eggbucket/archive/2012/02/02/2335697.html JUnit4概述 JUnit4是JUnit框架有史以来的最大改进, ...
- About LOCAL_PRIVATE_PLATFORM_APIS in Android.mk
LOCAL_PRIVATE_PLATFORM_APIS := true设置后,会使用sdk的hide的api來编译 在Android.mk中如果有LOCAL_SDK_VERSION 这个编译配置,就会 ...
- [原]openstack-kilo--issue(一) httpd汇总
/** 系统环境:redhat7.2 repo:163 openstack version : kilo author: lihaibo **/ 问题1:Invalid command 'group= ...
- tcp连接的状态变迁以及如何调整tcp连接中处于time_wait的时间
一.状态变迁图 二.time_wait状态 针对time_wait和close_wait有个简单的描述帮助理解: Due to the way TCP/IP works, connections ca ...
- psr-4
自动加载: <?php function autoload($className) { $className = ltrim($className, '\\'); $fileName = ''; ...