Hashtable与HashMap的区别
来源:互联网 发布:cs1.5优化教程视频 编辑:程序博客网 时间:2024/04/30 15:55
先说说Hashtable,我们看到java api文档中介绍,其实现了java.util.Dictonary< K ,V >类
如文档中介绍,Any non-null object can be used as a key or as a value,即不能将空对象放入Hashtable中
Unlike the new collection implementations, Hashtable is synchronized. If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.
在看上面一句话,意思是:不像集合框架的实现类,Hashtable是同步的(我也不太会翻译这句话,我自己理解的意思是Hashtable是线程安全的,即对于某些会出现线程安全问题的方法,都用synchronized来修饰)。如果不需要线程安全的实现,则建议使用HashMap来替代Hashtable。如果需要高并发线程安全的实现,则推荐使用ConcurrentHashMap来替代Hashtable
Hashtable是过去遗留下来的类,目的只是为了支持老的操作
下面我们来看看Hashtable的部分源码
//注意这里1!!!! public synchronized V put(K key, V value) { // Make sure the value is not null //注意这里2!!!! if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = hash(key); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { V old = e.value; e.value = value; return old; } } modCount++; if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; hash = hash(key); index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. Entry<K,V> e = tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; return null; }
下面我们来解读一下这个put方法
首先,注意1:是这个方法用了synchronized方法修饰,说明其是线程安全的
注意2:确定其存入的值不能为空,否则抛出空指针异常
首先我们要明白,设计者用数组保存键的信息(此处是键的信息,而不是键的本身),数组并不保存键的本身,而是通过键对象生成一个数字,将其作为数组的下标,即hashcode。
所以我们并不能保证不同的对象会生成不同的hashcode,有可能他们会生成相同的hashcode,这时候会出现”hash collision”。冲突由外部链接进行处理:数组并不直接保存值,而是保存值的list。然后对list中的值使用equals方法进行现行查询。这部分的查询自然比较慢,但是散列函数取得好的话,数组的每个位置就只有较少的值。
1.确认存入的键在hashtable中还未存在
2.首先根据其的hash码算出数组的下标,得到在数组中所对应的Entry< K , V >键值对,再跟键对象的hash码判断容器中是否存在这个键(若hash码相同,再依据equals进行查询),即满足(e.hash == hash) && e.key.equals(key)此条件时,说明容器中存在此键值对,则返回其值,否则继续循环
3.若不满足上述条件,则说明容器中无此键值对,但是根据hash码得出其键值对非空,则重新计算hash码,则将键值对装入hashtable的Entry链表中,并且将其放入table数组中,方便第二步的查询和get()方法的使用
相应的其一些可能涉及线程安全的方法如remove(Object key),contains(Object value) 等都用synchronized来修饰,以确保hashtable是线程安全的
下面我们来看看HashMap
HashMap继承的是java.util.AbstractMap< K , V >类,根据java API文档的介绍,HashMap permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.)
上面就说出了HashMap和Hashtable最重要的区别,即Hashtable除了不允许非空值和线程安全,其和HashMap没什么区别
**
即它们的区别:
1.HashMap允许有空的键值对,即空值和空键,而Hashtable不允许,若存入空值则抛出异常
2.Hashtable是线程安全的,HashMap是非线程安全的
**
现在看HashMap的put方法的源码
//注意这里1!!!!public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } //注意这里2!!!! if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } }
除了上面的两大区别以外,他们的执行过程都基本一样
我自己看源码觉得还有一点小小的不同的是:当发生了hash码冲突(table中的下标冲突)的时候,要将刚放入的键值对放到table数组中,Hashtable的做法是,重新计算hash值,调用rehash()方法,而HashMap的做法是先将table的数组大小进行扩容,再重新计算其hash值,再将键值对存入对应的table下标下!!!
- HashTable与HashMap的区别
- HashMap与Hashtable的区别
- Hashtable与HashMap的区别:
- HashMap 与 Hashtable 的区别?
- HashMap与HashTable的区别
- HashMap与Hashtable的区别
- HashMap与Hashtable的区别
- HashTable与HashMap的区别
- Hashtable与HashMap的区别
- HashMap与Hashtable的区别
- HashMap与HashTable的区别?
- hashtable与hashmap的区别
- HashMap与Hashtable的区别
- HashMap与Hashtable的区别
- HashMap与Hashtable的区别
- HashMap与Hashtable的区别
- hashtable与hashmap的区别
- HashMap与Hashtable的区别
- Android开发在string.xml文件中设置部分字体颜色大小
- 论文笔记 | Metric Learning with adaptive density discrimination
- 图解Linux命令之--userdel命令
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 F. Periodic Signal(FFT 优化乘法)
- 逞年轻多学习(2016/10/01)
- Hashtable与HashMap的区别
- codeforces-C. Journey(广搜+记录路径)
- 将你的Laravel应用部署到Heroku上
- ListView点击item底部弹出popupWindow删除、修改、取消选择框
- 嵌入式系统学习(三)-S5P4418 芯片存储空间分布说明
- Storage Classes in C++ Programming
- 【C/C++语言】指针常量与常量指针的区别
- 【POJ1011】Sticks-DFS+调整法剪枝
- 【myfocus】一款好用的焦点图轮播插件