Java 常用的三个集合类(2)
map.get(2)=萝卜
map.get(null)=黄瓜
set=[null, 1, 2, 3, 4]
Collection=[黄瓜, 白菜, 萝卜, 茄子, null]
2、HashMap 中作为键的对象必须重写Object的hashCode()方法和equals()方法
下面看一个我花了1个小时构思的例子,熟悉龙枪的朋友看起来会比较亲切,设定了龙和龙的巢穴,然后把它们用Map集合对应起来,我们可以根据龙查看它巢穴中的宝藏数量,例子只是为了说明hashCode这个知识点,所以未必有太强的故事性和合理性,凑合看吧: import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
// 龙和它的巢穴映射表
Map<dragon , Nest> map = new HashMap<dragon , Nest>();
// 在Map中放入四只克莱恩大陆上的龙
map.put(new Dragon("锐刃", 98), new Nest(98));
map.put(new Dragon("明镜", 95), new Nest(95));
map.put(new Dragon("碧雷", 176), new Nest(176));
map.put(new Dragon("玛烈", 255), new Nest(255));
// 查看宝藏
System.out.println("碧雷巢穴中有多少宝藏:" + map.get(new Dragon("碧雷", 176)).getTreasure()); }
}
// 龙
class Dragon {
Dragon(String name, int level) {
this.level = level;
= name;
}
// 龙的名字
private String name;
// 龙的级别
private int level;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
}
// 巢穴
class Nest {
//我研究的龙之常数
final int DRAGON_M = 4162; // 宝藏
private int treasure;
// 居住的龙的级别
private int level;
Nest(int level) {
this.level = level;
this.treasure = level * level * DRAGON_M;
}
int getTreasure() {
return treasure;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
this.treasure = level * level * DRAGON_M;
}
}
编译并运行查看结果:
Exception in thread "main" ng.NullPointerException
at Test.main(Test.java:18)
我们发现竟然报了错误,第18行出了空指针错误,也就是说get方法竟然没有拿到预期的巢穴对象。
在这里我们就要研究一下为什么取不到了。我们这里先解释一下HashMap的工作方式。
假设现在有个6张中奖彩票的存根,放在5个桶里(彩票首位只有1-5,首位是1的就放在一号桶,是2的就放在2号桶,依次类推),现在你拿了3张彩票来兑奖,一个号码是113,一个号码是213,一个号码是313。那么现在先兑第一张,取出一号桶里的存根发现存根号码和你的号码不符,所以你第一张没中奖。继续兑第二张,二号桶里就没存根所以就直接放弃了,把三号桶里的所有彩票存根都拿出来对应一番,最后发现有一个存根恰好是313,那么恭喜你中奖了。 HashMap在确定一个键对象和另一个键对象是否是相同时用了同样的方法,每个桶就是一个键对象的散列码值,桶里放的就是散列码相同的彩票存根,如果散列码不同,那么肯定没有相关元素存在,如果散列码相同,那么还要用键的equals()方法去比较是否相同,如果相同才认为是相同的键。简单的说就是 hashCode()相同 && equals()==true 时才算两者相同。
到了这里我们应该明白了,在没有重写一个对象的hashcode()和equals()方法之前,它们执行的是Object中对应的方法。而Object的hashcode()是用对象在内存中存放的位置计算出来的,每个对象实例都不相同。Object的equals()的实现更简单就是看两个对象是否==,也就是两个对象除非是同一个对象,否则根本不会相同。因此上面的例子虽然都是名字叫碧雷的龙,但是HashMap中却无法认可它们是相同的。
因此我们只有重写Key对象的hashCode()和equals()方法,才能避免这种情形出现,好在Eclipse可以帮我们自动生成一个类的hashCode()和equals(),我们把上面的例子加上这两个方法再试试看: import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
// 龙和它的巢穴映射表
Map<dragon , Nest> map = new HashMap<dragon , Nest>();
// 在Map中放入四只克莱恩大陆上的龙
map.put(new Dragon("锐刃", 98), new Nest(98));
map.put(new Dragon("明镜", 95), new Nest(95));
map.put(new Dragon("碧雷", 176), new Nest(176));
map.put(new Dragon("玛烈", 255), new Nest(255));
// 查看宝藏
System.out.println("碧雷巢穴中有多少宝藏:" + map.get(new Dragon("碧雷", 176)).getTreasure
());
}
}
// 龙
class Dragon {
Dragon(String name, int level) {
this.level = level;
= name;
}
// 龙的名字
private String name;
// 龙的级别
private int level;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + level;
result = PRIME * result + ((name == null) ? 0 : name.hashCode()); return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Dragon other = (Dragon) obj;
if (level != other.level)
return false;
if (name == null) {
if ( != null)
return false;
} else if (!name.equals())
return false;
return true;
}
}
// 巢穴
class Nest {
//我研究的龙之常数
final int DRAGON_M = 4162;
// 宝藏
private int treasure;
// 居住的龙的级别
private int level;
Nest(int level) {
this.level = level;
this.treasure = level * level * DRAGON_M; }
int getTreasure() {
return treasure;
}
public int getLevel() {
return level;
}
public void setLevel(int leve …… 此处隐藏:2282字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [资格考试]石油钻采专业设备项目可行性研究报告编
- [资格考试]2012-2013学年度第二学期麻风病防治知
- [资格考试]道路勘测设计 绪论
- [资格考试]控烟戒烟知识培训资料
- [资格考试]建设工程安全生产管理(三类人员安全员
- [资格考试]photoshop制作茶叶包装盒步骤平面效果
- [资格考试]授课进度计划表封面(09-10下施工)
- [资格考试]麦肯锡卓越工作方法读后感
- [资格考试]2007年广西区农村信用社招聘考试试题
- [资格考试]软件实施工程师笔试题
- [资格考试]2014年初三数学复习专练第一章 数与式(
- [资格考试]中国糯玉米汁饮料市场发展概况及投资战
- [资格考试]塑钢门窗安装((专项方案)15)
- [资格考试]初中数学答题卡模板2
- [资格考试]2015-2020年中国效率手册行业市场调查
- [资格考试]华北电力大学学习实践活动领导小组办公
- [资格考试]溃疡性结肠炎研究的新进展
- [资格考试]人教版高中语文1—5册(必修)背诵篇目名
- [资格考试]ISO9001-2018质量管理体系最新版标准
- [资格考试]论文之希尔顿酒店集团进入中国的战略研
- 全国中小学生转学申请表
- 《奇迹暖暖》17-支2文学少女小满(9)公
- 2019-2020学年八年级地理下册 第六章
- 2005年高考试题——英语(天津卷)
- 无纺布耐磨测试方法及标准
- 建筑工程施工劳动力安排计划
- (目录)中国中央空调行业市场深度调研分
- 中国期货价格期限结构模型实证分析
- AutoCAD 2016基础教程第2章 AutoCAD基
- 2014-2015学年西城初三期末数学试题及
- 机械加工工艺基础(完整版)
- 归因理论在管理中的应用[1]0
- 突破瓶颈 实现医院可持续发展
- 2014年南京师范大学商学院决策学招生目
- 现浇箱梁支架预压报告
- Excel_2010函数图表入门与实战
- 人教版新课标初中数学 13.1 轴对称 (
- Visual Basic 6.0程序设计教程电子教案
- 2010北京助理工程师考试复习《建筑施工
- 国外5大医疗互联网模式分析