仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 846|回复: 19
打印 上一主题 下一主题

[学习教程] 来看java的hashtable的用法

[复制链接]
简单生活 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:36:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Java到底会发战成什么样,让我们拭目以待吧,我始终坚信着java会更好。以上都是俺个人看法,欢迎大家一起交流.
Vector同意我们用一个数字从一系列对象中作出选择,以是它实践是将数字同对象联系关系起来了。但假设我们想依据其他尺度选择一系列对象呢?仓库就是如许的一个例子:它的选择尺度是“最初压进仓库的工具”。这类“从一系列对象当选择”的观点亦可叫作一个“映照”、“字典”大概“联系关系数组”。从观点上讲,它看起来象一个Vector,但却不是经由过程数字来查找对象,而是用另外一个对象来查找它们!这一般都属于一个程序中的主要历程。
在Java中,这个观点详细反应到笼统类Dictionary身上。该类的接口长短常直不雅的size()告知我们个中包括了几元素;isEmpty()判别是不是包括了元素(是则为true);put(Objectkey,Objectvalue)增加一个值(我们但愿的工具),并将其统一个键联系关系起来(想用于搜刮它的工具);get(Objectkey)取得与某个键对应的值;而remove(ObjectKey)用于从列表中删除“键-值”对。还可使用列举手艺:keys()发生对键的一个列举(Enumeration);而elements()发生对一切值的一个列举。这即是一个Dictionary(字典)的全体。
Dictionary的完成历程其实不贫苦。上面列出一种复杂的办法,它利用了两个Vector,一个用于包容键,另外一个用来包容值:
  1. //:AssocArray.java
  2. //SimpleversionofaDictionary
  3. importjava.util.*;
  4. publicclassAssocArrayextendsDictionary{
  5. privateVectorkeys=newVector();
  6. privateVectorvalues=newVector();
  7. publicintsize(){returnkeys.size();}
  8. publicbooleanisEmpty(){
  9. returnkeys.isEmpty();
  10. }
  11. publicObjectput(Objectkey,Objectvalue){
  12. keys.addElement(key);
  13. values.addElement(value);
  14. returnkey;
  15. }
  16. publicObjectget(Objectkey){
  17. intindex=keys.indexOf(key);
  18. //indexOf()Returns-1ifkeynotfound:
  19. if(index==-1)returnnull;
  20. returnvalues.elementAt(index);
  21. }
  22. publicObjectremove(Objectkey){
  23. intindex=keys.indexOf(key);
  24. if(index==-1)returnnull;
  25. keys.removeElementAt(index);
  26. Objectreturnval=values.elementAt(index);
  27. values.removeElementAt(index);
  28. returnreturnval;
  29. }
  30. publicEnumerationkeys(){
  31. returnkeys.elements();
  32. }
  33. publicEnumerationelements(){
  34. returnvalues.elements();
  35. }
  36. //Testit:
  37. publicstaticvoidmain(String[]args){
  38. AssocArrayaa=newAssocArray();
  39. for(charc=a;c<=z;c++)
  40. aa.put(String.valueOf(c),
  41. String.valueOf(c)
  42. .toUpperCase());
  43. char[]ca={a,e,i,o,u};
  44. for(inti=0;i<ca.length;i++)
  45. System.out.println("Uppercase:"+
  46. aa.get(String.valueOf(ca[i])));
  47. }
  48. }///:~
复制代码
在对AssocArray的界说中,我们注重到的第一个成绩是它“扩大”了字典。这意味着AssocArray属于Dictionary的一品种型,以是可对其收回与Dictionary一样的哀求。假如想天生本人的Dictionary,并且就在这里举行,那末要做的全体事变只是添补位于Dictionary内的一切办法(并且必需掩盖一切办法,由于它们——除构建器外——都是笼统的)。
Vectorkey和value经由过程一个尺度索引编号链接起来。也就是说,假如用“roof”的一个键和“blue”的一个值挪用put()——假定我们筹办将一个屋子的各部分与它们的油漆色彩联系关系起来,并且AssocArray里已有100个元素,那末“roof”就会有101个键元素,而“blue”有101个值元素。并且要注重一下get(),假设我们作为键传送“roof”,它就会发生与keys.index.Of()的索引编号,然后用谁人索引编号天生相干的值矢量内的值。
main()中举行的测试长短常复杂的;它只是将小写字符转换成年夜写字符,这明显可用更无效的体例举行。但它向我们展现出了AssocArray的壮大功效。
尺度Java库只包括Dictionary的一个变种,名为Hashtable(散列表,正文③)。Java的散列表具有与AssocArray不异的接口(由于二者都是从Dictionary承继来的)。但有一个方面却反应出了不同:实行效力。若细心想一想必需为一个get()做的事变,就会发明在一个Vector里搜刮键的速率要慢很多。但此时用散列表却能够加速很多速率。不用用冗杂的线性搜刮手艺来查找一个键,而是用一个特别的值,名为“散列码”。散列码能够猎取对象中的信息,然后将其转换成谁人对象“绝对独一”的整数(int)。一切对象都有一个散列码,而hashCode()是根类Object的一个办法。Hashtable猎取对象的hashCode(),然后用它疾速查找键。如许可以使功能失掉年夜幅度提拔(④)。散列表的详细事情道理已超越了本书的局限(⑤)——人人只必要晓得散列表是一种疾速的“字典”(Dictionary)便可,而字典是一种十分有效的工具。

③:如企图利用RMI(在第15章胪陈),应注重将远程对象置进散列表时会碰到一个成绩(参阅《CoreJava》,作者Conrell和Horstmann,Prentice-Hall1997年出书)
④:如这类速率的提拔仍旧不克不及满意你对功能的请求,乃至能够编写本人的散列表例程,从而进一步加速表格的检索历程。如许做可制止在与Object之间举行外型的工夫耽搁,也能够避开由Java类库散列表例程内建的同步历程。
⑤:我的晓得的最好参考读物是《PracticalAlgorithmsforProgrammers》,作者为AndrewBinstock和JohnRex,Addison-Wesley1995年出书。

作为使用散列表的一个例子,可思索用一个程序来查验Java的Math.random()办法的随机性究竟怎样。在幻想情形下,它应当发生一系列完善的随机散布数字。但为了考证这一点,我们必要天生数目浩瀚的随机数字,然后盘算落在分歧局限内的数字几。散列表能够极年夜简化这一事情,由于它能将对象同对象联系关系起来(此时是将Math.random()天生的值同那些值呈现的次数联系关系起来)。以下所示:
  1. //:Statistics.java
  2. //SimpledemonstrationofHashtable
  3. importjava.util.*;
  4. classCounter{
  5. inti=1;
  6. publicStringtoString(){
  7. returnInteger.toString(i);
  8. }
  9. }
  10. classStatistics{
  11. publicstaticvoidmain(String[]args){
  12. Hashtableht=newHashtable();
  13. for(inti=0;i<10000;i++){
  14. //Produceanumberbetween0and20:
  15. Integerr=
  16. newInteger((int)(Math.random()*20));
  17. if(ht.containsKey(r))
  18. ((Counter)ht.get(r)).i++;
  19. else
  20. ht.put(r,newCounter());
  21. }
  22. System.out.println(ht);
  23. }
  24. }///:~
复制代码
在main()中,每次发生一个随机数字,它城市封装到一个Integer对象里,使句柄可以伴同散列表一同利用(不成对一个汇合利用基础数据范例,只能利用对象句柄)。containKey()办法反省这个键是不是已在汇合里(也就是说,谁人数字之前发明过吗?)若已在汇合里,则get()办法取得谁人键联系关系的值,此时是一个Counter(计数器)对象。计数器内的值i随后会增添1,标明这个特定的随机数字又呈现了一次。
假设键之前还没有发明过,那末办法put()仍旧会在散列表内置进一个新的“键-值”对。在创立之初,Counter会本人的变量i主动初始化为1,它标记着该随机数字的第一次呈现。
为显现散列表,只需把它复杂地打印出来便可。HashtabletoString()办法能遍历一切键-值对,并为每对都挪用toString()。IntegertoString()是事前界说好的,可看到计数器利用的toString。一次运转的了局(增加了一些换行)以下:
  1. {19=526,18=533,17=460,16=513,15=521,14=495,
  2. 13=512,12=483,11=488,10=487,9=514,8=523,
  3. 7=497,6=487,5=480,4=489,3=509,2=503,1=475,
  4. 0=505}
复制代码
人人也许会对Counter类是不是需要感应困惑,它看起来仿佛基本没有封装类Integer的功效。为何不必int或Integer呢?现实上,因为一切汇合能包容的唯一对象句柄,以是基本不成以利用整数。学过汇合后,封装类的观点对人人来讲便可能更简单了解了,由于不成以将任何基础数据范例置进汇合里。但是,我们对Java封装器能做的独一事变就是将其初始化成一个特定的值,然后读取谁人值。也就是说,一旦封装器对象已创立,就没有举措改动一个值。这使得Integer封装器对办理我们的成绩毫偶然义,以是不能不创立一个新类,用它来满意本人的请求。

1.创立“关头”类
在后面的例子里,我们用一个尺度库的类(Integer)作为Hashtable的一个键利用。作为一个键,它能很好地事情,由于它已具有准确运转的一切前提。但在利用散列表的时分,一旦我们创立本人的类作为键利用,就会碰到一个很罕见的成绩。比方,假定一套天色预告体系将Groundhog(土拔鼠)对象婚配成Prediction(预告)。这看起来十分直不雅:我们创立两个类,然后将Groundhog作为键利用,而将Prediction作为值利用。以下所示:
  1. //:SpringDetector.java
  2. //Looksplausible,butdoesntworkright.
  3. importjava.util.*;
  4. classGroundhog{
  5. intghNumber;
  6. Groundhog(intn){ghNumber=n;}
  7. }
  8. classPrediction{
  9. booleanshadow=Math.random()>0.5;
  10. publicStringtoString(){
  11. if(shadow)
  12. return"SixmoreweeksofWinter!";
  13. else
  14. return"EarlySpring!";
  15. }
  16. }
  17. publicclassSpringDetector{
  18. publicstaticvoidmain(String[]args){
  19. Hashtableht=newHashtable();
  20. for(inti=0;i<10;i++)
  21. ht.put(newGroundhog(i),newPrediction());
  22. System.out.println("ht="+ht+"
  23. ");
  24. System.out.println(
  25. "Lookinguppredictionforgroundhog#3:");
  26. Groundhoggh=newGroundhog(3);
  27. if(ht.containsKey(gh))
  28. System.out.println((Prediction)ht.get(gh));
  29. }
  30. }///:~
复制代码
每一个Groundhog都具有一个标识号码,以是赤了在散列表中查找一个Prediction,只需唆使它“告知我与Groundhog号码3相干的Prediction”。Prediction类包括了一个布尔值,用Math.random()举行初始化,和一个toString()为我们注释了局。在main()中,用Groundhog和与它们相干的Prediction添补一个散列表。散列表被打印出来,以便我们看到它们的确已被添补。随后,用标识号码为3的一个Groundhog查找与Groundhog#3对应的预告。
看起来仿佛十分复杂,但实践是不成行的。成绩在于Groundhog是从通用的Object根类承继的(若现在未指定基本类,则一切类终极都是从Object承继的)。现实上是用Object的hashCode()办法天生每一个对象的散列码,并且默许情形下只利用它的对象的地点。以是,Groundhog(3)的第一个实例其实不会发生与Groundhog(3)第二个实例相称的散列码,而我们用第二个实例举行检索。
人人也许以为此时要做的全体事变就是准确地掩盖hashCode()。但如许做仍然行不克不及,除非再做另外一件事变:掩盖也属于Object一部分的equals()。当散列表试图判别我们的键是不是即是表内的某个键时,就会用到这个办法。一样地,默许的Object.equals()只是复杂地对照对象地点,以是一个Groundhog(3)其实不即是另外一个Groundhog(3)。
因而,为了在散列表中将本人的类作为键利用,必需同时掩盖hashCode()和equals(),就象上面展现的那样:
  1. //:SpringDetector2.java
  2. //Ifyoucreateaclassthatsusedasakeyin
  3. //aHashtable,youmustoverridehashCode()
  4. //andequals().
  5. importjava.util.*;
  6. classGroundhog2{
  7. intghNumber;
  8. Groundhog2(intn){ghNumber=n;}
  9. publicinthashCode(){returnghNumber;}
  10. publicbooleanequals(Objecto){
  11. return(oinstanceofGroundhog2)
  12. &&(ghNumber==((Groundhog2)o).ghNumber);
  13. }
  14. }
  15. publicclassSpringDetector2{
  16. publicstaticvoidmain(String[]args){
  17. Hashtableht=newHashtable();
  18. for(inti=0;i<10;i++)
  19. ht.put(newGroundhog2(i),newPrediction());
  20. System.out.println("ht="+ht+"
  21. ");
  22. System.out.println(
  23. "Lookinguppredictionforgroundhog#3:");
  24. Groundhog2gh=newGroundhog2(3);
  25. if(ht.containsKey(gh))
  26. System.out.println((Prediction)ht.get(gh));
  27. }
  28. }///:~
复制代码
注重这段代码利用了来自前一个例子的Prediction,以是SpringDetector.java必需起首编译,不然就会在试图编译SpringDetector2.java时失掉一个编译期毛病。
Groundhog2.hashCode()将土拔鼠号码作为一个标识符前往(在这个例子中,程序员必要包管没有两个土拔鼠用一样的ID号码并存)。为了前往一个举世无双的标识符,其实不必要hashCode(),equals()办法必需可以严厉判别两个对象是不是相称。
equals()办法要举行两种反省:反省对象是不是为null;若不为null,则持续反省是不是为Groundhog2的一个实例(要用到instanceof关头字,第11章会详加叙述)。即便为了持续实行equals(),它也应当是一个Groundhog2。正如人人看到的那样,这类对照创建在实践ghNumber的基本上。这一次一旦我们运转程序,就会看到它终究发生了准确的输入(很多Java库的类都掩盖了hashcode()和equals()办法,以便与本人供应的内容顺应)。

2.属性:Hashtable的一品种型
在本书的第一个例子中,我们利用了一个名为Properties(属性)的Hashtable范例。在谁人例子中,下述程序行:
Propertiesp=System.getProperties();
p.list(System.out);
挪用了一个名为getProperties()的static办法,用于取得一个特别的Properties对象,对体系的某些特性举行形貌。list()属于Properties的一个办法,可将内容发给我们选择的任何流式输入。也有一个save()办法,可用它将属性列表写进一个文件,以便往后用load()办法读取。
只管Properties类是从Hashtable承继的,但它也包括了一个散列表,用于包容“默许”属性的列表。以是假设没有在主列内外找到一个属性,就会主动搜刮默许属性。
Properties类亦可在我们的程序中利用(第17章的ClassScanner.java即是一例)。在Java库的用户文档中,常常能够找到更多、更具体的申明。
IDE是好。java中的IDE更是百花齐放,你用jbuilder能说jbuilder赶不上vs吗?用eclipse,net网页编程beans也很舒服啊。我就不明白“稍微差一些”那一些是从哪里差来的。
若相依 该用户已被删除
沙发
发表于 2015-1-19 09:13:52 | 只看该作者
是一种使用者不需花费很多时间学习的语言
柔情似水 该用户已被删除
板凳
发表于 2015-1-21 19:30:30 | 只看该作者
你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?
若天明 该用户已被删除
地板
发表于 2015-1-23 07:13:44 | 只看该作者
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
海妖 该用户已被删除
5#
发表于 2015-1-24 15:23:32 | 只看该作者
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
飘灵儿 该用户已被删除
6#
发表于 2015-2-1 19:13:51 | 只看该作者
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
精灵巫婆 该用户已被删除
7#
发表于 2015-2-2 18:51:35 来自手机 | 只看该作者
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
分手快乐 该用户已被删除
8#
发表于 2015-2-5 23:37:05 | 只看该作者
科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
不帅 该用户已被删除
9#
发表于 2015-3-2 16:46:05 | 只看该作者
另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。
只想知道 该用户已被删除
10#
发表于 2015-3-5 03:04:13 | 只看该作者
[url]http://www.jdon.com/[/url]去下载,或到同济技术论坛的服务器[url]ftp://nro.shtdu.edu.cn[/url]去下,安装上有什么问题,可以到论坛上去提问。
乐观 该用户已被删除
11#
发表于 2015-3-11 18:24:41 | 只看该作者
任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言
12#
发表于 2015-3-11 20:48:36 | 只看该作者
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
老尸 该用户已被删除
13#
发表于 2015-3-19 12:28:07 | 只看该作者
是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言
冷月葬花魂 该用户已被删除
14#
发表于 2015-3-20 08:10:56 | 只看该作者
Java 编程语言的风格十分接近C、C++语言。
莫相离 该用户已被删除
15#
发表于 2015-3-31 04:34:40 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
深爱那片海 该用户已被删除
16#
发表于 2015-4-4 16:07:48 | 只看该作者
你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。
小妖女 该用户已被删除
17#
发表于 2015-4-16 07:12:55 | 只看该作者
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
愤怒的大鸟 该用户已被删除
18#
发表于 2015-4-21 19:12:05 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
飘飘悠悠 该用户已被删除
19#
发表于 2015-4-21 19:35:13 | 只看该作者
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
再见西城 该用户已被删除
20#
发表于 2015-4-26 19:17:48 | 只看该作者
Java 编程语言的风格十分接近C、C++语言。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 17:05

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表