`
isiqi
  • 浏览: 16557046 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

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

阅读更多
在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的论坛,也把《Java虚拟机规范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《ThinkinginJava》翻了也找不到很好的答案,于是一气之下把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的源码如下

publicObjectput(Objectkey,Objectvalue){
Objectk=maskNull(key);

这个就是判断键值是否为空,并不很深奥,其实如果为空,它会返回一个staticObject作为键值,这就是为什么HashMap允许空键值的原因。

inthash=hash(k);
inti=indexFor(hash,table.length);

这连续的两步就是HashMap最牛的地方!研究完我都汗颜了,其中hash就是通过key这个Object的hashcode进行hash,然后通过indexFor获得在Objecttable的索引值。

table???不要惊讶,其实HashMap也神不到哪里去,它就是用table来放的。最牛的就是用hash能正确的返回索引。其中的hash算法,我跟JDK的作者Doug联系过,他建议我看看《Theartofprogramingvol3》可恨的是,我之前就一直在找,我都找不到,他这样一提,我就更加急了,可惜口袋空空啊~~5555

不知道大家有没有留意put其实是一个有返回的方法,它会把相同键值的put覆盖掉并返回旧的值!如下方法彻底说明了HashMap的结构,其实就是一个表加上在相应位置的Entry的链表:

for(Entrye=table[i];e!=null;e=e.next){
if(e.hash==hash&&eq(k,e.key)){
Objectoldvalue=e.value;
e.value=value;//把新的值赋予给对应键值。
e.recordAccess(this);//空方法,留待实现
returnoldvalue;//返回相同键值的对应的旧的值。
}
}
modCount++;//结构性更改的次数
addEntry(hash,k,value,i);//添加新元素,关键所在!
returnnull;//没有相同的键值返回
}

我们把关键的方法拿出来分析:

voidaddEntry(inthash,Objectkey,Objectvalue,intbucketIndex){
table[bucketIndex]=newEntry(hash,key,value,table[bucketIndex]);

因为hash的算法有可能令不同的键值有相同的hash码并有相同的table索引,如:key=“33”和key=Objectg的hash都是-8901334,那它经过indexfor之后的索引一定都为i,这样在new的时候这个Entry的next就会指向这个原本的table[i],再有下一个也如此,形成一个链表,和put的循环对定e.next获得旧的值。到这里,HashMap的结构,大家也十分明白了吧?

if(size++>=threshold)//这个threshold就是能实际容纳的量
resize(2*table.length);//超出这个容量就会将Objecttable重构

所谓的重构也不神,就是建一个两倍大的table(我在别的论坛上看到有人说是两倍加1,把我骗了),然后再一个个indexfor进去!注意!!这就是效率!!如果你能让你的HashMap不需要重构那么多次,效率会大大提高!
}

说到这里也差不多了,get比put简单得多,大家,了解put,get也差不了多少了。对于collections我是认为,它是适合广泛的,当不完全适合特有的,如果大家的程序需要特殊的用途,自己写吧,其实很简单。(作者是这样跟我说的,他还建议我用LinkedHashMap,我看了源码以后发现,LinkHashMap其实就是继承HashMap的,然后override相应的方法,有兴趣的同人,自己looklook)建个Objecttable,写相应的算法,就ok啦。

举个例子吧,像Vector,list啊什么的其实都很简单,最多就多了的同步的声明,其实如果要实现像Vector那种,插入,删除不多的,可以用一个Objecttable来实现,按索引存取,添加等。
如果插入,删除比较多的,可以建两个Objecttable,然后每个元素用含有next结构的,一个table存,如果要插入到i,但是i已经有元素,用next连起来,然后size++,并在另一个table记录,其位置。
分享到:
评论

相关推荐

    aduna-commons-collections-2.2.jar.zip

    10. **依赖管理**:作为Java项目的依赖,Aduna Commons Collections 2.2.jar通常会与其他Java库一起使用,例如Apache Commons Lang、Apache Commons Beanutils等,它们共同构成了强大的开发工具链。 总之,Aduna ...

    Java Collections.pdf

    《Java集合框架深度解析》 Java集合框架是Java编程语言中的一个重要组成部分,它为数据存储提供了丰富的类和接口。在本文中,我们将深入探讨Java集合框架的核心概念、设计原理以及实际应用。 首先,我们来理解Java...

    2014-蓝桥杯预赛-Java本科-B组真题

    6. **集合框架**:掌握ArrayList、LinkedList、HashSet、HashMap等集合类的使用,以及Collections工具类的常用方法。 7. **多线程**:理解线程的基本概念,会创建和使用Thread类或实现Runnable接口,掌握同步机制,...

    JAVA算法分析-很好的java思想

    Java标准库提供了多种排序算法实现,如Arrays.sort()内部采用的快速排序和归并排序,以及Collections.sort()默认使用的TimSort。理解这些排序算法的原理,有助于在实际开发中选择最适合的排序方式。 递归与分治策略...

    Java中对HashMap的深度分析

    找遍了大大小小的论坛,也把《Java 虚拟机规范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻了也找不到很好的答案,于是一气之下把JDK的 src 解压出来研究,扩然...

    Java深度历险

    - 分析部分JDK核心类库的源代码,如Object类、String类、Collections框架等,帮助读者理解Java标准库的设计理念。 通过阅读《Java深度历险》,读者不仅可以掌握Java语言的基本知识,还能深入了解其运行机制,提升...

    Effective-Java-2nd-Edition-(May-2008).zip_effective java

    以上只是《Effective Java》一书的部分主题,全书涵盖了大量Java编程的最佳实践和深度解析,是每个Java开发者案头必备的参考书。通过理解和应用这些知识点,开发者能够提升代码质量,降低维护成本,同时也能更好地...

    数据结构与算法分析java超高清pdf包含源码实现

    通过阅读《数据结构与算法分析Java版》,你不仅可以掌握基本的数据结构和算法,还能学习到如何使用Java Collections API来高效地处理数据。这对于提升编程能力、优化代码性能以及解决复杂问题至关重要。无论你是初学...

    Collections源码java-collections_analysis:手写spring(先)及java自带的集合框架源码分析(后)

    《Java集合框架源码深度解析:Collections及其背后的机制》 在Java编程中,集合框架扮演着至关重要的角色,它是处理对象存储、组织和操作的核心工具。本篇文章将深入探讨Collections类,以及它与Java自带的集合框架...

    Collections源码java-forester:Forester是Java和Ruby软件的开放源代码库的集合,用于系统发育组学和进化生物

    《Java Collections 源码深度解析与 Forester 在系统发育组学的应用》 在Java编程领域,Collections框架是核心部分之一,它提供了丰富的接口和类,使得数据操作变得高效且简洁。本文将深入探讨Collections框架的...

    Java学习书籍.pdf

    Java Collections Framework是Java库中的核心部分,包含了各种接口(如List、Set、Map)和实现(如ArrayList、LinkedList、HashMap)。这个框架使用了多种设计模式,学习它不仅可以帮助你更好地理解和使用Java标准库...

    java程序员试题及答案

    通过以上解析,我们可以看到Java在设计时对细节的关注,无论是从访问控制的安全性,还是数据结构的选择,或是输入输出流的高效处理,都体现了其作为一门成熟语言的深度和广度。这些知识点对于Java程序员来说,不仅是...

    数据结构和算法详细分析用C-python-java详解.rar

    通过阅读《数据结构与算法分析--C语言描述》、《数据结构与算法分析——Java语言描述》和《数据结构与算法:Python语言描述》这三本书,你将能够掌握这些关键概念,并能够在实际项目中灵活运用。

    Java 推荐读物

    - **深度解析:** 对于Java中的许多概念和技术进行了深入的剖析,例如泛型、异常处理、线程等。 - **实践导向:** 提供了大量的示例代码来帮助读者理解和掌握理论知识,同时也鼓励读者通过实践来加深理解。 **作者...

    Java2 参考大全

    《Java2参考大全》是一部深度全面的Java编程学习资料,主要涵盖了Java 2平台的核心技术和应用实践。作为一本Java教程,它旨在帮助开发者深入理解Java语言,并提升在实际开发中的应用能力。以下将从多个方面详细阐述...

    数据结构与算法分析(Java版)

    同时,Java提供丰富的工具类和接口,如Collections和Comparator,帮助我们操作和比较数据结构中的元素。 对于算法分析,我们需要掌握如何计算和分析算法的时间复杂度(运行时间随输入规模的增长速率)和空间复杂度...

    java的学习历程.pdf

    在数据结构方面,Java提供了一个强大的Collections Framework,包括ArrayList、LinkedList、HashMap等数据结构。《Java Collections》是一本专注于Java Collections API的书籍,适合初学者了解和掌握。进一步的学习...

    java程序员需要看的书

    这本书专注于Java集合框架,详细阐述了ArrayList、LinkedList、HashMap等数据结构的使用和实现,是理解Java Collections API的重要参考。此外,其他如《Data Structures in Java》、《Object-oriented Data ...

Global site tag (gtag.js) - Google Analytics