hash(散列)?java
散列數據結構,可是java這裏屏蔽了,直接就用封裝的形式把他封裝到了 HashSet,HashMap,HashTable中.其中HashTable已通過時了.算法
hash算法:java中指的hashCode()函數及其重寫.數組
目標:給每一個對象生成一個惟一的標示符數據結構
根據對象的特色爲每一個對象生成一個惟一hashCode,而後把這個hashCode做爲下標,把對象值做爲元素值保存到數組中(對象的引用).這個時候這個數組就能夠看作關聯數組.java中沒有關聯數組這個概念,單獨取了個名叫HashSet.函數
Hash的過程:編碼
拿到對象,調用他本身的hash算法(hashCode()方法),生成一個惟一的hash值,而後把這個值保存到數組中,整個過程就是hash.數組,和惟一值,和對象的關係,咱們就叫HashSet;spa
hash算法在java中就是指Object中的hashCode()函數裏面的算法,這一個是根據你寫的類來本身定義的.對象
hash哈希衝突:多個對象可能生成一個相同的hash值.索引
HashSet爲何無序,不可重複?接口
1 生成的hashCode沒有必定大小關係,就無所謂順序
2 每一個對象都必須生成一個惟一的hashCode(多個對象能夠生成相同的,可是還要比較值),若是是重複的對象,確定是生成同一個hashCode,而且值也是相同的.這個時候就沒有辦法惟一性查詢出某個數據.因此必須是不可重複的.全部的一切爲了數據的惟一標識.
HashSet和HashMap
1 HashSet 是HashMap的一個實現,本質是HashMap.而HashMap的數據結構是一個Hash表.
2 Hash表又叫散列表,其底層是經過hashCode()函數組成的一個數組,每一個數組的元素又是一個單向鏈表.每一個單項鍊表都有一個獨一無二hash值,就是數組的下標,也意味着每一個單項鍊表的節點的hash值是相同的.
怎麼向Hash表中添加元素.
1) 要添加的時候,HashMap保存的是映射關係,這個映射關係靠什麼來維護(Map.Entry(K,V)),是一個接口,那咱們就能夠傳入各類對象的映射關係.若是生成了重複的hash值怎麼辦?就會往HashTable,桶位上加一個單向鏈表單向鏈表中每一個對象都是一個Entry.
重點:2) 添加過程: 第一步:先調用要存儲的映射關係的key對象,而後調用key對象自身的hashCode()方法,生成hash碼,向數組中添加元素.若是沒有這個hash碼,就佔用一個數組的空間,保存這個key-value映射對象Entry.若是已經有了這個hash碼,就須要執行第二步.
第二步:equals(),把鍵的值挨個在hash碼相同的鏈表中進行比較,若是返回爲true那麼就表明該鏈表中已經有了這個key值,就放棄添加,若是沒有則返回false,就執行第三步.
第三步:就把數組中當前保存的那個節點向後移動一位(並非真的移動,只是我取得他內存地址,保存在新加入的那個元素的nextNode中),再把當前的這個映射關係對象Entry保存到數組中.
3) HashSet和Hashmap 初始化容量都是16,默認加載因子都是0.75.
索引數組:在內存空間上是連續的記數也是連續的,整體就是有序的
關聯數組:在內存空間上是連續的,記數不是連續的,就是無序的
哈希表:用hashCode()函數進行編碼的做爲下標的關聯數組.
咱們用的hashCode()函數可能會有重複的狀況,可是數組又規定不能重複,咱們再用equals()比較另一個外屬性(必須包含兩個比較,一個比較hashCode,另一個比較另一個屬性.)
hashSet:只保存了一個元素.
hashMap:是一個元素裏面保存兩個對象的映射關係,再把這個映射關係封裝成一個對象