Java hashset,關于HashMap,HashTable,HashSet淺析

 2023-11-19 阅读 23 评论 0

摘要:?首先,最重要的,HashMap 作為一個我們使用非常多的集合。最常被大家認知的是,它是一個key-value形式存儲數據的數據結構,可以實現快速的存,取操作。 關于HashMap的源碼,我們截取一部分分析: public class HashMap<K,V&g

?首先,最重要的,HashMap

作為一個我們使用非常多的集合。最常被大家認知的是,它是一個key-value形式存儲數據的數據結構,可以實現快速的存,取操作。
關于HashMap的源碼,我們截取一部分分析:
public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable
{/*** The default initial capacity - MUST be a power of two.*/static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16/*** The maximum capacity, used if a higher value is implicitly specified* by either of the constructors with arguments.* MUST be a power of two <= 1<<30.*/static final int MAXIMUM_CAPACITY = 1 << 30;/*** The load factor used when none specified in constructor.*/static final float DEFAULT_LOAD_FACTOR = 0.75f;/*** An empty table instance to share when the table is not inflated.*/static final Entry<?,?>[] EMPTY_TABLE = {};/*** The table, resized as necessary. Length MUST Always be a power of two.*/transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;

  

我們看到了它實現的接口有Serializable,說明他能序列化,有Cloneable,說明能被克隆,有Map<K,V>,說明是一個Map(廢話)。還有幾條有用的信息:第一:有個默認初始容量,第二:有個最大容量,第三:有個調節因子,第四:有個數組。
再往后看,發現這玩意又是由一個數組組成的,而這個數組的初始容量是16,最大容量是2^30。當然這個調節因子這個地方暫且不提。
既然是用數組存儲,我們存的又是Key-Value形式,這數組是怎么運作的呢?這里用往Map中添加數據為例說明:
public V put(K key, V value) {if (table == EMPTY_TABLE) {inflateTable(threshold);}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;}}modCount++;addEntry(hash, key, value, i);return null;
} 
由于篇幅問題,我們就不粘貼太多代碼了,先說一下,我們的hashMap實現是有一個數組實現,數組中存儲的都是Entry<Key,Value>節點,Entry是HashMap的內部類,存儲的是key,value,key的哈希值和下一個節點,具體可以自己查看源碼。
這里我們看到,首先,如果這個數字為空,則先初始化一個數組,如果要添加的key為空,直接進行空Key的添加(這里HashMap是允許有一個key為空的值的)。如果key不為空,則算出key的哈希值,根據哈希值,查找對應數組的位置,如果此key存在,就是說有相同的key,則覆蓋(其實是鏈到后面的串,每個數組元素往后一個鏈表),沒有則直接添加。這么一說其實就簡單了,我們查詢什么的就可以根據哈希值直接定位到相應的Entry,然后扔出來就是了。

然后我們說說HashSet:

public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, java.io.Serializable
{static final long serialVersionUID = -5024744406713321676L;private transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();/*** Constructs a new, empty set; the backing <tt>HashMap</tt> instance has* default initial capacity (16) and load factor (0.75).*/public HashSet() {map = new HashMap<>();}

這里就可以看出,HashSet底層就是一個HashMap,而它跟HashMap不同的就是它是實現Set接口,所以他的數據必須唯一。

?最后是HashTable:

?由于篇幅問題,就不貼代碼了,跟HashMap差不多,底層也是一個數組。就說一下它跟HashMap主要的區別吧:
第一:HashMap允許一個null的key和任意value都有null,而HashTable無論key和value都不能為空。
第二:HashTable可以看做是線程安全的HashMap。

轉載于:https://www.cnblogs.com/jeyson/p/6425199.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/181837.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息