HashMap和HashTable两个是jdk.util包下2个经常使用的类,他们都继承AbstractMap抽象类,该抽象类实现了Map接口
原理
:hashMap和HashTable是根据key的hashcode来直接定位数组中的每个下标值,这样就不用进行for循环,然后因为不同的key会产生相同的hashcode,在同个table[i]下标下有多个。key-value这样的Entry,所以在Entry中又有一个next成员变量对这些Entry实现一个链表形式。如图:
hashMap:首先HashMap的组成是一个数组加链表
的结构,也可以理解为数组里面的每个元素其实是一个链表,即a->b->c,通过a来获得b,b可以获得c,在hashMap中使用的key-value的模式,这种模式其实是封装在一个object当中,在这个object中有2个成员变量一个是key,一个是value。当然在hashMap中这个object的类真实名称是Entry在hashmap中的674行,在Entry中存放的有四个值:key value next hash //key即hashMap中的key,value即对应的值,next即链表中的下一个Entry对象,hash是每个key的hashcode(在内存中hashcode代表的是key是内存中存放的地址).
在hashMap中有三个构造函数,当然无非是几个之间相互调用而已:最主要的一个构造函数如下:
//initialCapaity:传入的hashMap参数,loadFactor:对于hashMap的空间和时间效率因素
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
//上面的语句都没什么用,废话,直接看下面
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;//这里其实是一个2的平方,所以当你创建一个hashmap以为方法的第一个参数为10,以为hashmap的数组长度就是10就错了,是16
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);//这个就是当一个hashMap中数据个数超过threshold的时候就会进行数据扩展(下面进行说明)
table = new Entry[capacity];
init();//jdk中保留
}
//下面介绍最重要的2个方法:其余的方法我想基本都不是什么问题了
//首先是put方法:
public V put(K key, V value) {
if (key == null)//当key值为null的时候进行特定的放入数据:由此可见hashMap的key是可以为null的
return putForNullKey(value);
int hash = hash(key.hashCode());//获得key的hashcode
int i = indexFor(hash, table.length);//这个是hashcode和数组长度进行与比较,这样可以使得i的值不操作数组长度并且跟hashcode是有直接相连的
for (Entry<K,V> e = table[i]; e != null; e = e.next) {//下面是数组中的一个table[i]确定的元素进行链表循环
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {//当key值原来已经存在的时候进行值替换
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;//这个参数是hashmap中用来统计你对当前hashmap进行了多少次操作
addEntry(hash, key, value, i);//这个方法是将key和value放入数组中
return null;
}
//具体添加
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];//讲table[i]中的第一个Entry传给临时变量
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);//table[i]中指向这个新创建的Entry,并将临时变量传递给next
if (size++ >= threshold)//用来数组的扩容
resize(2 * table.length);
}
下面讲解下为什么使用threshold,默认是(数组长度/0.75)因为数组是链表形式所以数组是可以放无限个Entry(内存允许),但对于查找效率将会随着链表的长度增加而降低,所以需要在Entry个数达到一定数量的时候进行数组的扩充。
HashTable:HashTable的原理和HashMap的原理是一样(或者说基本都是一样)的,但是看源代码可以发现,hashTable中每个方法都添加一个同步机制synchronized,也就是
hashTable是线程安全的。还有一个区别就是hashtabel中key和value值都不允许为null,具体看hashtable的方法。
备注:我想把我看到的和分析的写下来,对自己是非常有帮助的,希望看到的朋友如果觉得有什么不对的地方能指出来,Thanks
!
- 大小: 27.6 KB
分享到:
相关推荐
1. 解压缩"java-jdk1.6-jdk-6u45-windows-x64.zip"文件,这将释放出"jdk-6u45-windows-x64.exe"可执行文件。 2. 双击运行"jdk-6u45-windows-x64.exe",安装向导会引导你完成安装过程。通常,你需要选择安装路径,...
aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-...
Java Development Kit (JDK) 是Java编程语言的核心组件,它为开发者提供了编译、调试和运行Java应用程序所需的所有工具。JDK1.6是Oracle公司发布的一个较早版本,适用于Windows操作系统。在这个解压版中,用户无需...
2部分: jdk-1.6-windows-64-01 jdk-1.6-windows-64-02
压缩包中的文件`jdk-6u45-windows-i586.exe`是JDK 1.6更新45的Windows 32位安装程序。安装步骤通常包括: 1. 下载并运行安装程序。 2. 遵循安装向导的提示,选择安装路径和组件。 3. 设置环境变量,包括`JAVA_HOME`...
三部分: jdk-1.6-linux-64-1 jdk-1.6-linux-64-2 jdk-1.6-linux-64-3
三部分: jdk-1.6-linux-64-1 jdk-1.6-linux-64-2 jdk-1.6-linux-64-3
在描述中,“jdk1.6 windows64版本 解压完直接双击安装即可”,意味着用户在下载该压缩包后,不需要进行复杂的设置或编译过程,只需将其解压缩,然后通过简单的鼠标操作,即双击名为“jdk-6u45-windows-x64.exe”的...
logback-cfca-jdk1.6-3.1.0.0.jar
三部分: jdk-1.6-windows-32-1 jdk-1.6-windows-32-2 jdk-1.6-windows-32-3
三部分: jdk-1.6-linux-64-1 jdk-1.6-linux-64-2 jdk-1.6-linux-64-3
标题中的"jdk-jdk1.6.0.24-windows-i586.exe"是一个Java Development Kit(JDK)的安装程序,适用于Windows操作系统且为32位版本。JDK是Oracle公司提供的一个用于开发和运行Java应用程序的软件包。这个特定的版本,...
- 这可能是ZXing库的完整源码包,专门针对JDK1.6编译,包含了所有必要的源文件和资源,供开发者进行更深度的定制和集成。 总之,ZXing库是一个强大的条形码和二维码工具,这个特别适配JDK1.6的版本为那些仍在使用...
深入理解JDK 1.6的源码对于Java开发者来说至关重要,因为它揭示了语言核心库的工作原理,有助于优化代码、理解和解决潜在问题。 1. **Java虚拟机(JVM)**:JDK 1.6中的JVM是Java程序执行的基础,它的主要职责是...
jdk1.6安装版官方下载,JDK详细介绍 JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。 SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。 EE(J2EE),...
在安装和配置JDK 1.6.0.24时,用户需要注意环境变量的设置,特别是`JAVA_HOME`和`PATH`,确保系统能够正确找到Java命令。64位版本需要与64位操作系统兼容,以充分利用大内存优势。对于那些依赖于特定JDK版本的旧项目...
jdk-1.6-linux-32-1 jdk-1.6-linux-32-2 jdk-1.6-linux-32-3
《Sun JDK 1.6内存管理--调优篇》深入探讨了Java开发中的关键环节——JVM内存管理和性能优化。Sun JDK 1.6作为早期的Java开发环境,其内存管理机制对于理解现代JVM的工作原理至关重要。本文将详细解析JVM内存结构,...
运行这个文件时,通常需要赋予它执行权限(例如,使用`chmod +x jdk-6u34-linux-x64.bin`命令),然后通过终端执行它来启动安装过程。 另一个文件是"linux-jdk安装说明.txt",这提供了一个详细的指南,指导用户如何...
自己整理的完整版jdk1.6的source,包含了jdk包中原先的src.zip,自己重新压缩过。可以直接使用解压后的src.zip 完全解压后的代码有138M 方便调试跟踪 分了2部分,这是第二部分