HashSet HashTable HashMap的區別 及其Java集合介紹


(1)HashSet是set的一個實現類,hashMap是Map的一個實現類,同時hashMap是hashTable的替代品(為什么后面會講到).

(2)HashSet以對象作為元素,而HashMap以(key-value)的一組對象作為元素,且HashSet拒絕接受重復的對象.HashMap可以看作三個視圖:key的Set,value的Collection,Entry的Set。 這里HashSet就是其實就是HashMap的一個視圖。

HashSet內部就是使用Hashmap實現的,和Hashmap不同的是它不需要Key和Value兩個值。        

往hashset中插入對象其實只不過是內部做了

            public boolean add(Object o) {

                      return map.put(o, PRESENT)==null;
            }

 現在來看hastTable和hashMap的區別:

1. HashMap

1)  hashmap的數據結構 

     Hashmap是一個數組和鏈表的結合體(在數據結構稱“鏈表散列“),如下圖示:

        當我們往hashmap中put元素的時候,先根據key的hash值得到這個元素在數組中的位置(即下標),然后就可以把這個元素放到對應的位置中了。如果這個元素所在的位子上已經存放有其他元素了,那么在同一個位子上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。

2)使用

復制代碼
Map map = new HashMap();
map.put("Rajib Sarma","100");
map.put("Rajib Sarma","200");//The value "100" is replaced by "200".
map.put("Sazid Ahmed","200");

Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
復制代碼

2. HashTable和HashMap區別

第一,繼承不同。

public class Hashtable extends Dictionary<> implements Map<>
public class HashMap extends AbstractMap<> implements Map<>

具體可見Java API.

第二

Hashtable 中的方法是同步的,而HashMap中的方法在缺省情況下是非同步的。在多線程並發的環境下,可以直接使用Hashtable,但是要使用HashMap的話就要自己增加同步處理了。

第三

Hashtable中,key和value都不允許出現null值。

在HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。當get()方法返回null值時,即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。

第四,兩個遍歷方式的內部實現上不同。

Hashtable、HashMap都使用了 Iterator。而由於歷史原因,Hashtable還使用了Enumeration的方式 。

第五

哈希值的使用不同,HashTable直接使用對象的hashCode,如下:

   int hash = key.hashCode();
      int index = (hash & 0x7FFFFFFF) % tab.length;

而HashMap重新計算hash值。

而HashMap重新計算hash值,而且用與代替求模:

int hash = hash(k);
int i = indexFor(hash, table.length);

static int hash(Object x) {
   int h = x.hashCode();
   h += ~(h << 9);
   h ^= (h >>> 14);
   h += (h << 4);
   h ^= (h >>> 10);
   return h;
}
static int indexFor(int h, int length) {
   return h & (length-1);
}

第六

Hashtable和HashMap它們兩個內部實現方式的數組的初始大小和擴容的方式。HashTable中hash數組默認大小是11,增加的方式是 old*2+1。HashMap中hash數組的默認大小是16,而且一定是2的指數。

 

其它的一些資料:

    1.HashTable有一個contains(Object value),功能和containsValue(Object value)功能一樣。
    2.HashTable使用Enumeration,HashMap使用Iterator。
      以上只是一些比較突出的區別,當然他們的實現上還是有很多不同的,比如

下面都代表了Java中的集合,這里主要從其元素是否有序,是否可重復來進行區別記憶,以便恰當地使用,當然還存在同步方面的差異,見上一篇相關文章。


 


有序否


允許元素重復否


Collection




List




Set


AbstractSet




HashSet


TreeSet


是(用二叉樹排序)


Map


AbstractMap



使用key-value來映射和存儲數據,Key必須惟一,value可以重復


HashMap


TreeMap


是(用二叉樹排序)

 

   List 接口對Collection進行了簡單的擴充,它的具體實現類常用的有ArrayList和LinkedList。你可以將任何東西放到一個List容器中,並在需要時從中取出。ArrayList從其命名中可以看出它是一種類似數組的形式進行存儲,因此它的隨機訪問速度極快,而LinkedList的內部實現是鏈表,它適合於在鏈表中間需要頻繁進行插入和刪除操作。在具體應用時可以根據需要自由選擇。前面說的Iterator只能對容器進行向前遍歷,而 ListIterator則繼承了Iterator的思想,並提供了對List進行雙向遍歷的方法。 

   Set接口也是 Collection的一種擴展,而與List不同的時,在Set中的對象元素不能重復,也就是說你不能把同樣的東西兩次放入同一個Set容器中。它的常用具體實現有HashSet和TreeSet類。HashSet能快速定位一個元素,但是你放到HashSet中的對象需要實現hashCode()方法,它使用了前面說過的哈希碼的算法。而TreeSet則將放入其中的元素按序存放,這就要求你放入其中的對象是可排序的,這就用到了集合框架提供的另外兩個實用類Comparable和Comparator。一個類是可排序的,它就應該實現Comparable接口。有時多個類具有相同的排序算法,那就不需要在每分別重復定義相同的排序算法,只要實現Comparator接口即可。集合框架中還有兩個很實用的公用類:Collections和 Arrays。Collections提供了對一個Collection容器進行諸如排序、復制、查找和填充等一些非常有用的方法,Arrays則是對一個數組進行類似的操作。 


   Map是一種把鍵對象和值對象進行關聯的容器,而一個值對象又可以是一個Map,依次類推,這樣就可形成一個多級映射。對於鍵對象來說,像Set一樣,一個Map容器中的鍵對象不允許重復,這是為了保持查找結果的一致性;如果有兩個鍵對象一樣,那你想得到那個鍵對象所對應的值對象時就有問題了,可能你得到的並不是你想的那個值對象,結果會造成混亂,所以鍵的唯一性很重要,也是符合集合的性質的。當然在使用過程中,某個鍵所對應的值對象可能會發生變化,這時會按照最后一次修改的值對象與鍵對應。對於值對象則沒有唯一性的要求。你可以將任意多個鍵都映射到一個值對象上,這不會發生任何問題(不過對你的使用卻可能會造成不便,你不知道你得到的到底是那一個鍵所對應的值對象)。Map有兩種比較常用的實現: HashMap和TreeMap。HashMap也用到了哈希碼的算法,以便快速查找一個鍵,TreeMap則是對鍵按序存放,因此它便有一些擴展的方法,比如firstKey(),lastKey()等,你還可以從TreeMap中指定一個范圍以取得其子Map。鍵和值的關聯很簡單,用pub (Object key,Object value)方法即可將一個鍵與一個值對象相關聯。用get(Object key)可得到與此key對象所對應的值對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM