使用对象作为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类 ...
随机推荐
- 【调试错误】找不到 System.Web.Mvc 引用
今天调试新项目,从svn上clone下来,发现运行不了. System.Web.Mvc 显示黄色叹号 解决方案如下: 安装一个 MVC 的插件.AspNetMVC2_VS2008.exe 下载地址:h ...
- 【python】flask 开启 debug 模式
方法一: 直接在run的时候添加debug from flask import Flask app = Flask(__name__) @app.route('/') def hello_world( ...
- 开始使用ARC
Automatic Reference Counting (ARC)是编译器自动管理Objective-C对象的一个功能,相对于不得不考虑retain和release操作来说,ARC让我们有更多的精力 ...
- 【Spring Boot&&Spring Cloud系列】Spring Boot初识
项目代码地址:https://github.com/AndyFlower/Spring-Boot-Learn/tree/master/Spring-boot-helloworld 一.Spring B ...
- pip安装python包出现Cannot fetch index base URL http://pypi.python.org/simple/
pipinstall***安装python包,出现 Cannot fetch index base URL http://pypi.python.org/simple /错误提示或者直接安装不成功. ...
- FileInputStream 和 FileOutputStream
简介 FileInputStream和FileOutputStream都是用来处理二进制数据源磁盘文件的流的. 他们分别派生自顶层抽象类InputStream和OutputStream FileInp ...
- iOS - 获取安装所有App的Bundle ID
先导入#import <objc/runtime.h>头文件 使用runtime获取设备上的所有app的bundle id // Class LSApplicationWorkspace_ ...
- thinkCMF----如何写标签
ThinkCMF写标签的地方:
- CentOS7.5搭建Solr7.4.0单机服务
一.Solr安装环境 1.官方参考文档 Solr教程参考指南:http://lucene.apache.org/solr/guide/7_4/solr-tutorial.html 2.Solr运行环境 ...
- Python的一个命名空间冲突,关于from-import机制
from os import * #import os def foo(): a = listdir("trainingDigits") b = open("traini ...