教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 文库大全 > 资格考试 >

Java 常用的三个集合类(2)

来源:网络收集 时间:2025-04-28
导读: map.get(2)=萝卜 map.get(null)=黄瓜 set=[null, 1, 2, 3, 4] Collection=[黄瓜, 白菜, 萝卜, 茄子, null] 2、HashMap 中作为键的对象必须重写Object的hashCode()方法和equals()方法 下面看一个我花了1个小时构思的

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字,全部文档内容请下载后查看。喜欢就下载吧 ……

Java 常用的三个集合类(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wenku/107555.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)