`

MAP例子

阅读更多
首先介绍一下什么是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语言的特性。

分享到:
评论

相关推荐

    google地图例子,google Map例子

    简单的google地图例子,google Map例子

    Google Map 例子源代码

    这个“Google Map例子源代码”压缩包显然包含了使用Google Maps API进行开发的一些示例代码,这对于学习和理解如何利用Google Maps API进行应用开发非常有帮助。 首先,我们要了解的是Google Maps API的基础概念。...

    STL map例子

    在本例子中,我们将深入探讨`map`的基本操作,包括插入元素、删除元素、修改元素以及查询元素。 1. **创建和初始化map** 在C++中,我们可以通过`std::map`声明一个空的map容器,例如: ```cpp std::map, std::...

    一个简单的google map例子代码

    简单的Google Map例子 &lt;script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"&gt;&lt;/script&gt; #map { height: 400px; width: 100%; } 请输入地名"&gt; ()"&gt;定位 &lt;div id="map"&gt; ...

    STL的map例子agtbouns STL的map例子agtbouns

    在STL中,`map`是一个关联容器,它存储键值对,每个键都是唯一的,并且通过键来访问其对应的值。`map`的数据结构通常实现为红黑树,保证了插入、查找和删除操作的时间复杂度为O(log n)。 `map`的使用主要包括以下几...

    google map例子

    以下是对这个"google map例子"中涉及的知识点的详细解释: 1. **Google Map API**:Google Map API是Google提供的一套JavaScript库,允许开发者在其网站上嵌入交互式地图。它提供了各种功能,如地图显示、标记添加...

    iphone map例子

    标题“iphone map例子”指的是与在iPhone上开发地图应用程序相关的示例代码或教程。这个描述表明,提供的资源可能是一个实际的项目文件或者一系列代码片段,专门用于帮助开发者理解和实现地图功能在iOS应用中的集成...

    Android google map API例子

    Android google map API例子

    echart2.0map例子.rar

    echart2.0地图使用接送数据 1.如果地图不全 ,或者需要绘制新的图 2.可以按照json或者js里面的数据格式,添加新的geo坐标数据 3.geo生成比较多,推荐 http://geojson.io可以导入修改或者在线生成

    google map应用实例

    在IT领域,Google Map是一款广泛使用的在线地图服务,它提供了丰富的功能,如定位、导航、路线规划、街景查看等。本应用实例将探讨如何利用Google Map API在离线环境中实现地图服务,这对于那些网络不稳定或者需要在...

    java中map的使用实例

    在Java编程语言中,Map接口是集合框架的重要组成部分,它提供了键值对(key-value pairs)的存储方式。Map不是列表或数组,而是允许我们通过一个键(key)来查找对应的值(value)。本篇文章将深入讲解Map的使用实例...

    map map openlayers例子

    在"map map openlayers例子"中,我们主要探讨的是如何使用OpenLayers创建和操作地图。首先,我们需要引入OpenLayers库的JavaScript文件。通常,这可以通过CDN链接或者本地文件引用完成。例如: ```html ...

    google map实例

    在IT领域,Google Map API是开发者们常用的工具,用于在网页上集成地图功能。这个"google map实例"是一个使用JavaScript编程语言,结合Google Maps API创建的应用示例。下面将详细介绍这个实例涉及的关键知识点。 ...

    Mapobject开发例子

    在“MapObject2.0与VB结合所开发的例子”中,开发者通常会利用VB的事件驱动编程模型,结合MapObject的控件和方法,实现以下功能: 1. 初始化地图:设置地图的基本属性,如地图投影、比例尺、初始位置等。 2. 加载...

    C++map使用小例子

    在本示例中,“C++map使用小例子”提供了关于如何在C++程序中使用`std::map`的基本操作和应用。 `std::map`的主要特点和操作包括: 1. **插入元素**:可以使用`insert`函数或直接使用下标运算符`[]`来插入键值对。...

    Android AIDL中Map参数传递的问题详解

    "Android AIDL中Map参数传递的问题详解" Android AIDL中Map参数传递的问题详解是 Android 应用程序接口定义语言(AIDL)中的一個重要课题。AIDL 是 Android 操作系统中的一個接口定义语言,用于定义应用程序之间的...

    STL的map的一个例子agtbouns STL的map的一个例子agtbouns

    在这个例子中,我们关注的是STL中的`map`容器,它是一个关联容器,可以将键(key)与值(value)进行一对一的映射。 `map`容器的主要特性: 1. **有序性**:`map`中的元素是按照键的升序排列的。这意味着你可以快速...

    google map 代码例子

    本示例将围绕"google map 代码例子"这一主题,通过提供的两个文件——`google map API.ppt`和`GoogleMapsDemo`,深入探讨如何在Android项目中实现Google Maps的功能。 `google map API.ppt`可能包含的是关于Google ...

    GoogleMap离线Api例子

    这个"GoogleMap离线Api例子"是一个示例项目,它演示了如何利用Google Maps API来实现离线地图功能,并结合了水经注的数据源。下面我们将详细探讨这个例子中的关键知识点。 首先,Google Maps API是Google提供的一套...

    mapserver例子程序

    To install: ... - edit "itasca.map" to reflect your configuration (the WEB section, paramters IMAGEPATH and IMAGEURL need to be changed) - point your browser at index.html and it should work

Global site tag (gtag.js) - Google Analytics