动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.WAP手机上的问卷调查系统的构建.
.复制、传递和比较数据.
.在RMS中存储和读取数据.
.地图的设计与绘制.
.GreedySnake贪吃蛇-测试版.
.课程介绍(6) SL-285 高级Java编程.
.Java桌面应用程序设计新贵:SWT简.
.JAVA学习笔记swingJFrame窗口学习.
.Java中finalize()的另类用法(1).
.link-list java版.
.设计模式之Facade(外观).
.在tomcat5中配置数据库连接池(D.
.Java对Domino Objects的访问 (3.
.利用UDPSockets技术实现IP多点传.
.用line_as_stream 简化流的读取.
.专家为您详解JAVA数据库基本操作.
.为什么TEXT字段不能存取大于4K的.
.struts构建文件上传(3).
.Apache服务器配置全攻略.
.用SQLJ开发数据库(3).

Java Collections--HashMap深度分析与比较

发表日期:2008-1-5 |



  在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的要害。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的论坛,也把《Java 虚拟机规范》
  
  《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻了也找不到很好的答案,于是一气之下把JDK的 src 解压出来研究,扩然开朗,遂写此文,跟大家分享感受和顺便验证我理解还有没有漏洞。 这里就拿HashMap来研究(嘻嘻~~是开刀)
  
  HashMap可谓JDK的一大实用工具,把各个Object映射起来,实现了“键--值”对应的快速存取。当实际里面做了些什么呢?
  
  在这之前,先介绍一下负载因子和容量的属性。大家都知道其实一个 HashMap 的实际容量就 因子*容量,其默认值是 16×0.75=12; 这个很重要,对效率很一定影响!当存入HashMap的对象超过这个容量时,HashMap 就会重新构造存取表。这就是一个大问题,我后面慢慢介绍,反正,假如你已经知道你大概要存放多少个对象,最好设为该实际容量的能接受的数字。
  
  两个要害的方法,put和get:
  先有这样一个概念,HashMap是声明了 Map,Cloneable, Serializable 接口,和继续了 AbstractMap 类,里面的 Iterator 其实主要都是其内部类HashIterator 和其他几个 iterator 类实现,当然还有一个很重要的继续了Map.Entry 的 Entry 内部类,由于大家都有源代码,大家有爱好可以看看这部分,我主要想说明的是 Entry 内部类。它包含了hash,value,key 和next 这四个属性,很重要。put的源码如下
  
  public Object put(Object key, Object value) {
  Object k = maskNull(key);
  
  这个就是判定键值是否为空,并不很深奥,其实假如为空,它会返回一个static Object 作为键值,这就是为什么HashMap答应空键值的原因。
  
  int hash = hash(k);
  int i = indexFor(hash, table.length);
  
  这连续的两步就是 HashMap 最牛的地方!研究完我都汗颜了,其中 hash 就是通过 key 这个Object的 hashcode 进行 hash,然后通过 indexFor 获得在Object table的索引值。
  
  table???不要惊奇,其实HashMap也神不到哪里去,它就是用 table 来放的。最牛的就是用 hash 能正确的返回索引。其中的hash算法,我跟JDK的作者 Doug 联系过,他建议我看看《The art of programing vol3》可恨的是,我之前就一直在找,我都找不到,他这样一提,我就更加急了,可惜口袋空空啊~~5555
  
  不知道大家有没有留意 put 其实是一个有返回的方法,它会把相同键值的 put 覆盖掉并返回旧的值!如下方法彻底说明了 HashMap 的结构,其实就是一个表加上在相应位置的Entry的链表:
  
  for (Entry e = table[i]; e != null; e = e.next) {
  if (e.hash == hash && eq(k, e.key)) {
  Object oldvalue = e.value;
  e.value = value;   //把新的值赋予给对应键值。
  e.recordAccess(this);  //空方法,留待实现
  return oldvalue;   //返回相同键值的对应的旧的值。
  }
  }
  modCount++;   //结构性更改的次数
  addEntry(hash, k, value, i);   //添加新元素,要害所在!
  return null;   //没有相同的键值返回
  }
  
  我们把要害的方法拿出来分析:
  
  void addEntry(int hash, Object key, Object value, int bUCketIndex) {
  table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]);
  
  因为 hash 的算法有可能令不同的键值有相同的hash码并有相同的table索引,如:key=“33”和key=Object g的hash都是-8901334,那它经过indexfor之后的索引一定都为i,这样在new的时候这个Entry的next就会指向这个原本的table[i],再有下一个也如此,形成一个链表,和put的循环对定e.next获得旧的值。到这里,HashMap的结构,大家也十分明白了吧?
  
  if (size++ >= threshold)   //这个threshold就是能实际容纳的量
  resize(2 * table.length);  //超出这个容量就会将Object table重构
  
  所谓的重构也不神,就是建一个两倍大的table(我在别的论坛上看到有人说是两倍加1,把我骗了),然后再一个个indexfor进去!注重!!这就是效率!!假如你能让你的HashMap不需要重构那么多次,效率会大大提高!
  }
  
  说到这里也差不多了,get比put简单得多,大家,了解put,get也差不了多少了。对于collections我是认为,它是适合广泛的,当不完全适合特有的,假如大家的程序需要非凡的用途,自己写吧,其实很简单。(作者是这样跟我说的,他还建议我用LinkedHashMap,我看了源码以后发现,LinkHashMap其实就是继续HashMap的,然后override相应的方法,有爱好的同人,自己looklook)建个 Object table,写相应的算法,就ok啦。
  
  举个例子吧,像 Vector,list 啊什么的其实都很简单,最多就多了的同步的声明,其实假如要实现像Vector那种,插入,删除不多的,可以用一个Object table来实现,按索引存取,添加等。
  假如插入,删除比较多的,可以建两个Object table,然后每个元素用含有next结构的,一个table存,假如要插入到i,但是i已经有元素,用next连起来,然后size++,并在另一个table记录,其位置。
上一篇:关于 mysql5 改密码后不能登录问题的解答 人气:386
下一篇:运用 DBUnit 进行高效的单元测试 人气:609
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-9-6 Movie34电影搜索引擎 v3.0
2008-9-6 wap2.0仿帝国建站喜用 v2.0
2008-9-6 免费人才招聘网 宽屏版 v3.01
2008-9-6 喜喔喔视频采集程序 v1.0 beta
2008-9-6 ASP客户管理系统
2008-9-6 主流驿站中秋祝福程序
2008-9-6 php实现msn协议的类
2008-9-5 Coppermine Photo Gallery v1.4.
2008-9-5 清松网络日记本 v2.4
2008-8-23 Mini WinMount V0.4
2008-8-23 Vista优化大师3.11正式版
2008-8-23 Wine 1.13
2008-8-23 KlipFolio 5.0 Build 5899-80
2008-8-23 Windows Sysinternals Desktops
2008-8-23 OneTap Movies1.2破解版
2008-8-23 AnnotaterPDF阅读1.1.503 破解版
2008-8-23 SoundMeter分贝测量仪 v1.0汉化破
2008-8-23 iDrum音乐节拍1.0破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | Html转换js | js/vbs加密 | md5加密 | 进制转换
实用工具:汉字翻译拼音 | 符号对照表 | 个税计算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号