Java提供了container classes来解册一问题。container classes包括两个部分QCollection和Map。它们的l构是这LQ?/p>
本文重点介绍HashMap。首先介l一下什么是Map。在数组中我们是通过数组下标来对其内容烦引的Q而在Map中我们通过对象来对对象q行索引Q用来烦引的对象叫做keyQ其对应的对象叫做value。在下文中会有例子具体说明?/p>
再来看看HashMap和TreeMap有什么区别。HashMap通过hashcode对其内容q行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得C个有序的l果你就应该使用TreeMapQHashMap中元素的排列序是不固定的)?/p>
下面pq入本文的主题了。先举个例子说明一下怎样使用HashMap:
import java.util.*;
public class Exp1 { class Ctime{ |
在HashMap中通过get()来获取valueQ通过put()来插入valueQContainsKey()则用来检验对象是否已l存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的斚w差异q不大?/p>
前面介绍了,HashMap是基于HashCode的,在所有对象的类Object中有一个HashCode()ҎQ但是它和equalsҎ一Pq不能适用于所有的情况Q这h们就需要重写自qHashCode()Ҏ。下面就举这样一个例子:
import java.util.*;
public class Exp2 { class Element{ class Figureout{ |
在这个例子中QElement用来索引对象Figureout,也即Element为keyQFigureout为value。在Figureout中随机生成一个QҎQ如果它?.5大,打印“OK!”,否则打印“Impossible!”。之后查看Element(3)对应的Figureoutl果如何?/p>
l果却发玎ͼ无论你运行多次Q得到的l果都是“Not found”。也是说烦引Element(3)q不在HashMap中。这怎么可能呢?
原因得慢慢来_Element的HashCodeҎl承自ObjectQ而Object中的HashCodeҎq回的HashCode对应于当前的地址Q也是说对于不同的对象Q即使它们的内容完全相同Q用HashCodeQ)q回的g会不同。这样实际上q背了我们的意图。因为我们在使用HashMapӞ希望利用相同内容的对象烦引得到相同的目标对象Q这需要HashCode()在此时能够返回相同的倹{在上面的例子中Q我们期望new Element(i) (i=5)与 Element test=new Element(5)是相同的Q而实际上q是两个不同的对象,管它们的内容相同,但它们在内存中的地址不同。因此很自然的,上面的程序得不到我们设想的结果。下面对ElementcL改如下:
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的g为hashcodeq回Q这样对于相同内容的对象来说它们的hashcode也就相同了。而覆盖equals()是ؓ了在HashMap判断两个key是否相等时ɾl果有意义(有关重写equals()的内容可以参考我的另一文章《重新编写ObjectcM的方?》)。修改后的程序运行结果如下:
h2:
Get the result for Element:
Impossible!
误住:如果你想有效的用HashMapQ你必重写在其的HashCode()?/p>
q有两条重写HashCode()的原则:
至于W二条原则的具体原因Q有兴趣者可以参考Bruce Eckel的《Thinking in Java》,在那里有对HashMap内部实现原理的介l,q里׃赘述了?/p>
掌握了这两条原则Q你p够用好HashMap~写自己的程序了。不知道大家注意没有Qjava.lang.Object中提供的三个ҎQclone()Qequals()和hashCode()虽然很典型,但在很多情况下都不能够适用Q它们只是简单的由对象的地址得出l果。这需要我们在自己的程序中重写它们Q其实javacd中也重写了千千万万个q样的方法。利用面向对象的多态性——覆盖,Java的设计者很优雅的构ZJava的结构,也更加体CJava是一门纯OOP语言的特性?/p>
Java提供的Collection和Map的功能是十分强大的,它们能够使你的程序实现方式更为灵z,执行效率更高。希望本文能够对大家更好的用HashMap有所帮助?