首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。在下文中会有例子具体说明。
再来看看HashMap和TreeMap有什么区别。HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。
package com.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
public class HashMain {
public static void main(String args[]){
Map map=new HashMap();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c", "ccc");
map.put("d", "ddd");
Iterator iter=map.keySet().iterator();
while(iter.hasNext()){
Object key=iter.next();
System.out.println("map key "+key.toString()+" Values:"+map.get(key));
}
TreeMap tap=new TreeMap();
tap.put("a", "aaa");
tap.put("b", "bbb");
tap.put("c", "ccc");
tap.put("d", "ddd");
Iterator iter2=tap.keySet().iterator();
while(iter2.hasNext()){
Object key=iter2.next();
System.out.println("tap key "+key.toString()+"values="+tap.get(key));
}
}
}
结果:
map key d Values:ddd
map key a Values:aaa
map key c Values:ccc
map key b Values:bbb
tap key avalues=aaa
tap key bvalues=bbb
tap key cvalues=ccc
tap key dvalues=ddd
package com.map;
import java.util.*;
public class Exp2 {
public static void main(String args[]){
HashMap h2=new HashMap();
for(int i=0;i<10;i++)
h2.put(new Element(i), new Figureout());
System.out.println("H2: ");
System.out.println("Get the result for Element!");
Element test=new Element(5);
if(h2.containsKey(test))
System.out.println((Figureout)h2.get(test));
else
System.out.println("Not found!");
}
}
class Element{
int number;
public Element(int i){
number=i;
}
public int hashCode(){
return number;
}
public boolean equals(Object o){
return(o instanceof Element)&&(number==((Element)o).number);
}
}
class Figureout{
Random r=new Random();
boolean possible=r.nextDouble()>0.5;
public String toString(){
if(possible)
return "OK!";
else
return "Imposible!";
}
}
package com.map;
import java.util.*;
public class Exp2 {
public static void main(String args[]){
HashMap h2=new HashMap();
for(int i=0;i<10;i++)
h2.put(new Element(i), new Figureout());
System.out.println("H2: ");
System.out.println("Get the result for Element!");
Element test=new Element(5);
if(h2.containsKey(test))
System.out.println((Figureout)h2.get(test));
else
System.out.println("Not found!");
}
}
class Element{
int number;
public Element(int i){
number=i;
}
public int hashCode(){
return number;
}
public boolean equals(Object o){
return(o instanceof Element)&&(number==((Element)o).number);
}
}
class Figureout{
Random r=new Random();
boolean possible=r.nextDouble()>0.5;
public String toString(){
if(possible)
return "OK!";
else
return "Imposible!";
}
}在这个例子中,Element用来索引对象Figureout,也即Element为key,Figureout为 value。在Figureout中随机生成一个浮点数,如果它比0.5大,打印"OK!",否则打印"Impossible!"。之后查看 Element(3)对应的Figureout结果如何。
结果却发现,无论你运行多少次,得到的结果都是"Not found"。也就是说索引Element(3)并不在HashMap中。这怎么可能呢?
原因得慢慢来说:Element的HashCode方法继承自Object,而Object中的HashCode方法返回的HashCode对应于当前的地址,也就是说对于不同的对象,即使它们的内容完全相同,用HashCode()返回的值也会不同。这样实际上违背了我们的意图。因为我们在使用HashMap时,希望利用相同内容的对象索引得到相同的目标对象,这就需要HashCode()在此时能够返回相同的值。在上面的例子中,我们期望new Element(i) (i=5)与 Element test=new Element(5)是相同的,而实际上这是两个不同的对象,尽管它们的内容相同,但它们在内存中的地址不同。因此很自然的,上面的程序得不到我们设想的结果。下面对Element类更改如下:
class Element{
int number;
public Element(int n){
number=n;
}
public int hashCode(){
return number;
}
public boolean equals(Object o){
return (o instanceof Element) && (number==((Element)o).number);
}
}
在这里Element覆盖了Object中的hashCode()和equals()方法。覆盖hashCode()使其以number的值作为hashcode返回,这样对于相同内容的对象来说它们的hashcode也就相同了。而覆盖equals()是为了在 HashMap判断两个key是否相等时使结果有意义(有关重写equals()的内容可以参考我的另一篇文章《重新编写Object类中的方法》)。修改后的程序运行结果如下:
h2:
Get the result for Element:
Impossible!
请记住:如果你想有效的使用HashMap,你就必须重写在其的HashCode()。
还有两条重写HashCode()的原则:
不必对每个不同的对象都产生一个唯一的hashcode,只要你的HashCode方法使get()能够得到put()放进去的内容就可以了。即"不为一原则"。
生成hashcode的算法尽量使hashcode的值分散一些,不要很多hashcode都集中在一个范围内,这样有利于提高HashMap的性能。即"分散原则"。
至于第二条原则的具体原因,有兴趣者可以参考Bruce Eckel的《Thinking in Java》,在那里有对HashMap内部实现原理的介绍,这里就不赘述了。
掌握了这两条原则,你就能够用好HashMap编写自己的程序了。不知道大家注意没有,java.lang.Object中提供的三个方法: clone(),equals()和hashCode()虽然很典型,但在很多情况下都不能够适用,它们只是简单的由对象的地址得出结果。这就需要我们在自己的程序中重写它们,其实java类库中也重写了千千万万个这样的方法。利用面向对象的多态性——覆盖,Java的设计者很优雅的构建了Java的结构,也更加体现了Java是一门纯OOP语言的特性。
分享到:
相关推荐
组成原理课程实验:MIPS 流水线CPU、实现36条指令、转发、冒险检测-内含源码和说明书.zip
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
CEA二次开发脚本:用于ECSP配比设计
环形数组
环形数组
附件是母亲节祝福 Python 代码(包含详细介绍),文件绿色安全,请大家放心下载,仅供交流学习使用,无任何商业目的!
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
max111111111
"攻防世界"这一术语广泛应用于网络安全领域,它生动描绘了一个持续演进的技术战场,其中攻击者与防御者围绕着数据保护、系统安全及网络基础设施的完整性展开激烈的智斗。在这个虚拟而又现实交织的舞台上,知识、技能与创新成为了决定胜负的关键要素。以下是对这个复杂多维攻防世界的深度资源描述: 在一个由代码编织的宇宙里,"攻防世界"不仅是一场技术较量,更是对策略、耐心与适应能力的考验。想象一个庞大的数字迷宫,其中数据如同珍贵的宝藏,被各式各样的防火墙、加密协议和安全系统重重保护。而另一边,潜伏着一群技艺高超的黑客,他们利用漏洞、社会工程学以及先进的攻击手段,试图穿透这些防线,揭露系统的脆弱之处。 对于防御方而言,构建坚不可摧的安全体系是永恒的目标。这要求他们精通最新的安全技术,如入侵检测系统(IDS)、安全信息和事件管理(SIEM)平台、以及人工智能驱动的威胁狩猎工具。同时,定期进行渗透测试和红蓝对抗演练,模拟真实攻击场景,以发现并修补潜在漏洞。此外,培养安全意识,教育员工识别钓鱼邮件、恶意软件等,也是构建第一道防线的重要环节。 攻击者一方,则聚焦于不断探索未知漏洞(零日漏洞)、开发定制化恶意软
关于java出租车计价器设计与实现 总共4个模块 (1)出租车计价系统可以实现出租车信息的管理。 1.1出租车信息的查询:通过数据库查询出租车的车型,车号,以及是否可用 1.2出租车信息的增加:向数据库中添加出租车的车型,车号,以及是否可用 1.3出租车信息的修改:对数据库中已经存在的出租车的车型,车号,以及是否可用的信息进行修改 1.4出租车信息的删除:删除数据库中已经存储的出租车的信息 (2)出租车计价系统可以实现司机信息的管理。 2.1司机信息的查询:通过数据库查询出司机的年龄,性别,学历,名字等信息 2.2司机信息的增加:向数据库中添加司机的年龄,性别,学历,名字等信息 2.3司机信息的修改:对数据库中已经存在的司机的年龄,性别,学历,名字等信息进行修改 2.4司机信息的删除:删除数据库中已经存储的司机的信息 (3)出租车计价系统可以实现出租车计价功能。 3.1通过java多线程,模拟出租车在路上的情景 3.2通过距离计费的方式,将订单的时间,乘客的信息,订单的价格等插入数据库中 (4)出租车计价系统可以实
私信博主免费获取真题解析以及代码
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
附件是C语言输出母亲节祝福(内含详细描述),文件绿色安全,请大家放心下载,仅供交流学习使用,无任何商业目的!
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
仰卧起坐YOLOV8-POSE,C++,只需要OPENCV
行动学习指导手册glq.ppt
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
计算机网络资料复习pdf
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。