Java集合

HashMap HashTable List ArrayList Set
  
HashMap和HashTable的區別
HashMap的實現原理,key的hash算法
哪些集合是有序的(List)?哪些是無序的(Set、HashMap)?
  
ArrayList的線程安全問題,一個線程在讀,一個線程在寫會怎麼樣?它是線程安全的嗎?
  
HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完成了Map接口,
主要區別在於HashMap允許空(null)鍵值(key),由於非線程安全,效率上可能高於Hashtable。

HashMap允許將null作爲一個entry的key或者value,而Hashtable不允許。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因爲contains方法容易讓人引起誤解。 

Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要自己爲它的方法實現同步,
而HashMap 就必須爲之提供外同步(Collections.synchronizedMap)。 

Hashtable和HashMap採用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。
(HashMap不是線程安全的,但其在單線程程序中的性能比HashTable要高,HashTable支持線程同步保證線程安全而導致性能下降)


Collection是最基本的集合接口

不論 Collection 的實際類型如何,它都支持一個 iterator() 的方法,該方法返回一個迭代子,

使用該迭代子即可逐一訪問 Collection 中每一個元素
Collection 接口派生的兩個接口是 List 和 Set。
Collection 接口提供的主要方法: 
boolean add(Object o) 添加對象到集合; 
boolean remove(Object o) 刪除指定的對象; 
int size() 返回當前集合中元素的數量; 
boolean contains(Object o) 查找集合中是否有指定的對象; 
boolean isEmpty() 判斷集合是否爲空; 
Iterator iterator() 返回一個迭代器; 
boolean containsAll(Collection c) 查找集合中是否有集合 C 中的元素; 
boolean addAll(Collection c) 將集合 C 中所有的元素添加給該集合; 
void clear() 刪除集合中所有元素; 
void removeAll(Collection c) 從集合中刪除 C 集合中也有的元素; 

void retainAll(Collection c) 從集合中刪除集合 C 中不包含的元素。

---

所有類都在 java.util 這個包裏
  Collection
├List
├LinkedList
├ArrayList
│Vector
  └Stack
└Set
  Map
├Hashtable
├HashMap
└WeakHashMap

List接口是有序的Collection,List 允許有相同的元素

Map 沒有繼承 Collection 接口。Map 提供 Key 到 Value 的映射,一個 Map 中不能包含相同的 Key,
每個 Key 只能映射一個 Value。Map 接口提供 3 種集合的視圖,Map 的內容可以被當作一組 Key 集合,一組 Value 集合,
或者一組 Key-Value 映射。 
Map 提供的主要方法: 
boolean equals(Object o) 比較對象; 
boolean remove(Object o) 刪除一個對象; 
put(Object key,Object value) 添加 key 和 value。

集合最多能放多少元素?跟機器的內存有關,只要內存沒有溢出,理論上可以放無限個。????

HashMap能放多少元素? 2147483647(2^31-1) ,也就是Int的最大值,HashMap在不考慮Hash衝突的情況下也一樣。

正解,如過考慮Hash衝突,由於HashMap使用“數組+鏈表”的方式存儲數據,一個HashMap最多可以有(2^31-1)個鏈表.

一個鏈表可以包含多少個元素?由於64bit JVM的引用類型長度(可以)爲8字節,所以一個鏈表最多可以存放(2^63-1)個元素。

HashMap,可以存放的最多元素是:(2^31-1)*(2^63-1)個? 當然不是。一個JVM虛擬機裏最多隻能存在(2^63-1)個對象!!!
原因前面已說,因爲應用類型的長度爲8字節。

由於JVM啓動起來已經生成了很多對象,所以實際上我們寫代碼也不可能new(2^63-1)這麼多個對象。

上面沒有考慮JVM實際上能使用多少內存,一個對象至少佔用16字節,加上上引用8字節就是24字節了。
所以實際上JVM能分配出來的對象遠沒有那麼多。

-->使用for循環與使用迭代器iterator的對比

效率上的各有有事

採用ArrayList對隨機訪問比較快,而for循環中的get()方法,採用的即是隨機訪問的方法,因此在ArrayList裏,for循環較快

採用LinkedList則是順序訪問比較快,iterator中的next()方法,採用的即是順序訪問的方法,因此在LinkedList裏,使用iterator較快

從數據結構角度分析,for循環適合訪問順序結構,可以根據下標快速獲取指定元素.而Iterator 適合訪問鏈式結構,
因爲迭代器是通過next()和Pre()來定位的.可以訪問沒有順序的集合.

而使用 Iterator 的好處在於可以使用相同方式去遍歷集合中元素,而不用考慮集合類的內部實現
(只要它實現了 java.lang.Iterable 接口),如果使用 Iterator 來遍歷集合中元素,一旦不再使用 List 轉而使用 Set 來組織數據,
那遍歷元素的代碼不用做任何修改,如果使用 for 來遍歷,那所有遍歷此集合的算法都得做相應調整,因爲List有序,Set無序,
結構不同,他們的訪問算法也不一樣.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章