Java中的集合(Collection)有三類,一類是List,一類是Queue,再有一類就是Set。 前兩個集合內的元素是有序的,元素能夠重複;最後一個集合內的元素無序,但元素不可重複。html
Set:java
1.用於存儲無序(存入和取出的順序不必定相同)元素,值不能重複數組
2.對象的相等性本質是對象hashCode值(java是依據對象的內存地址計算出的此序號,不一樣對象的hashcode不必定不同)判斷的,若是想要讓兩個不一樣的對象視爲相等的,就必須覆蓋Object的hashCode方法和equals方法,好比string類就重寫了hashcode方法,算出的hashcode值並非對象的實際內存地址,equals也被重寫了安全
String.hashcode().net
String.equals線程
1.先驗證是不是否是同一個對象設計
2.再驗證是不是同一類型(String),而後驗證值是否相等3d
Hashset也是支持序列化、淺拷貝的指針
Hashset內部仍是Hashset,只不過調用它的add直接放入的再也不是鍵值對code
看下其add方法:
直接調用map.put放入e所表明的的鍵以及present成員變量
而這裏的map就是hashset內部存儲值的結構,能夠看到其鍵是放入的,鍵所對應的值是object的實例
既然其用的hashmap,那麼其構造方法實際上就是定義hashmap,因此就是hashmap的那四種構造方法
那麼取值的時候不像hashmap那麼方即可以直接取某個鍵對應的值,取hashset中的值是得到一個迭代器,取得內部hashmap全部的鍵而後遍歷再進行操做
因此其內部存儲時結構也和hashmap結構同樣了,同時hashset也是非線程安全的
1.前者有序,可存放重複值,後者無序,不可存放重複值,由於hashmap鍵不能重複
2.Arraylist被填滿擴充1.5倍,Hashset擴充機制和hashmap相同
HashTable實現的map接口,支持序列化和淺拷貝
hashtable也是"拉鍊法"實現的hash表(只是數組加單鏈表),其內部存儲結構爲entry數組,和hashmap相似,其也有負載因子和初始容量
其構造方法也有4種
第一種以下支持初始指定容量和負載因子,此時將給entry分配內存空間,而且初始化閾值爲初始容量和(2的31次-1)-8(最大值字節數)+1的較小值
第二種只指定初始化大小
第三種使用默認初始容量和負載因子,初始容量爲11
第四種則是直接放入一個map進來初始化構造一個hashtable,此時的hashtable容量將變爲放入的map的鍵值對的個數的2倍和默認容量的較大值,而後再將map放入
而hashmap這裏是和hashtable不同的,初始化時將用放入的map的鍵值數量/負載因子+0.75,算出的值再和2的30次方作比較,取二者較小值和閾值進行比較,並賦值閾值爲大於算出值最接近的2的次方值,便於後面resize擴容,而後後面再經過循壞將map中的值依次放入
1.HashTable 基於 Dictionary 類,而 HashMap 是基於 AbstractMap。Dictionary 是任何可將鍵映射到相應值的類的抽象父類, AbstractMap 是基於 Map 接口的實現,但hashtable和hashmap兩者都實現了Map接口
2.hashmap能夠放鍵和值均爲null的值,可是這樣的值你也只能放一個進去,因此hashmap中判斷是否存在某個鍵要用containskey(鍵一定是惟一的),而不能用get,所以能有多個鍵對應的value都是null,而hashtable的鍵和值不能夠爲null,不然將會報空指針錯誤
hashmap的處理:
因此hashmap考慮到了這種key爲null的狀況,讓其hash算出來爲0,不爲null的key再調用object的hashcode方法算hash
hashmap的get方法以下圖,不存在也有可能返回null或者鍵的值爲null,沒法判斷
hashtable的處理:
hashtable的設計並無考慮這麼多,而是直接調用其key的hashcode,那麼null.hashcode,必將報錯
hashtable將檢測放入的鍵對應的值是否爲null
3.hashmap在默認狀況下是非線程安全的,而hashtable覺得基本public方法都是用synchronized修飾的,所以其爲同步的
4.二者的擴容方式不同,hashmap擴容是resize方法,容量變爲old*2,而hashtable是rehash方法,容量變爲old*2+1,
5.二者內部遍歷實現不同:
hashmap的鍵值遍歷爲iterator
hashtable的鍵值遍歷爲Enumerator
6.獲取鍵所在的位置時的方法不一樣:
hashmap中首先用與邏輯代替了模運算加快了速度,2的n次方-1位全1二進制位再與key的hash與算出鍵值對的位置,而且其hash值並非單純的hashcode,而是用到了key的hashcode的高16位來作異或運算
hashtable中是根據key直接算一個hashcode(可能爲負值),而後再和2的31次方-1作與算出來的正值再模當前hash表的長度,而後肯定鍵值對的位置,那麼取模的效率確定沒有與邏輯的運行效率更高
https://blog.csdn.net/fujiakai/article/details/51585767 hashmap和hashtable區別
https://wiki.jikexueyuan.com/project/java-collection/hashtable.html hashmap實現原理