同步性:
Vector 是線程安全的,也就是說是它的方法之間是線程同步的,而 ArrayList 是線
程序不安全的,它的方法之間是線程不一樣步的。若是隻有一個線程會訪問到集合,那
最好是使用 ArrayList,由於它不考慮線程安全,效率會高些;若是有多個線程會訪問
到集合,那最好是使用 Vector,由於不須要咱們本身再去考慮和編寫線程安全的代
碼。java
備註:對於 Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,
記住 Vector 與 Hashtable 是舊的,是 java 一誕生就提供了的,它們是線程安全
的,ArrayList 與 HashMap 是 java2 時才提供的,它們是線程不安全的。因此,我
們講課時先講老的。編程
數據增加:
ArrayList 與 Vector 都有一個初始的容量大小,當存儲進它們裏面的元素的個數超
過了容量時,就須要增長 ArrayList 與 Vector 的存儲空間,每次要增長存儲空間
時,不是隻增長一個存儲單元,而是增長多個存儲單元,每次增長的存儲單元的個數
在內存空間利用與程序效率之間要取得必定的平衡。Vector 默認增加爲原來兩倍,而
ArrayList 的增加策略在文檔中沒有明確規定(從源代碼看到的是增加爲原來的 1.5
倍)。ArrayList 與 Vector 均可以設置初始的空間大小,Vector 還能夠設置增加的
空間大小,而 ArrayList 沒有提供設置增加空間的方法。
總結:即 Vector 增加原來的一倍,ArrayList 增長原來的 0.5 倍。數組
說說 ArrayList,Vector, LinkedList 的存儲性能和特性。
ArrayList 和 Vector 都是使用數組方式存儲數據,此數組元素數大於實際存儲的數
據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組
元素移動等內存操做,因此索引數據快而插入數據慢,Vector 因爲使用了
synchronized 方法(線程安全)。
一般性能上較 ArrayList 差,而 LinkedList 使用雙向鏈表實現存儲,按序號索引數
據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插
入速度較快 。
ArrayList 在查找時速度快,LinkedList 在插入與刪除時更具優點.安全
快速失敗 (fail-fast) 和安全失敗 (fail-safe) 的區別是什麼?
Iterator 的安全失敗是基於對底層集合作拷貝,所以,它不受源集合上修改的影響。
java.util 包下面的全部的集合類都是快速失敗的,而 java.util.concurrent 包下面的
全部的類都是安全失敗的。快速失敗的迭代器會拋出
ConcurrentModificationException 異常,而安全失敗的迭代器永遠不會拋出這樣的
異常。數據結構
hashmap 的數據結構。
在 java 編程語言中,最基本的結構就是兩種,一個是數組,另一個是模擬指針
(引用),全部的數據結構均可以用這兩個基本結構來構造的,hashmap 也不例
外。Hashmap 其實是一個數組和鏈表的結合體(在數據結構中,通常稱之爲 「鏈
表散列 「)
enter image description here框架
HashMap 的工做原理是什麼?
Java 中的 HashMap 是以鍵值對 (key-value) 的形式存儲元素的。HashMap 須要
一個 hash 函數,它使用 hashCode()和 equals()方法來向集合 / 從集合添加和檢
索元素。當調用 put() 方法的時候,HashMap 會計算 key 的 hash 值,而後把鍵
值對存儲在集合中合適的索引上。 若是 key 已經存在了,value 會被更新成新值。
HashMap 的一些重要的特性是它的容量 (capacity),負載因子 (load factor) 和擴
容極限(threshold resizing)。編程語言
Hashmap 何時進行擴容呢?
當 hashmap 中的元素個數超過數組大小 loadFactor 時,就會進行數組擴容,
loadFactor 的默認值爲 0.75,也就是說,默認狀況下,數組大小爲 16,那麼當
hashmap 中元素個數超過 160.75=12 的時候,就把數組的大小擴展爲 216=32,
即擴大一倍,而後從新計算每一個元素在數組中的位置,而這是一個很是消耗性能的操
做,因此若是咱們已經預知 hashmap 中元素的個數,那麼預設元素的個數可以有效
的提升 hashmap 的性能。好比說,咱們有 1000 個元素 new HashMap(1000),
可是理論上來說 new HashMap(1024) 更合適,不過上面 annegu 已經說過,即便
是 1000,hashmap 也自動會將其設置爲 1024。 可是 new HashMap(1024) 還
不是更合適的,由於 0.751000 < 1000, 也就是說爲了讓 0.75 size > 1000, 咱們
必須這樣 new HashMap(2048) 才最合適,既考慮了 & 的問題,也避免了 resize
的問題。ide
List 表示有前後順序的集合, 注意,不是那種按年齡、按大小、按價格之類的排序。
當咱們屢次調用 add(Obj e) 方法時,每次加入的對象就像火車站買票有排隊順序一
樣,按先來後到的順序排序。有時候,也能夠插隊,即調用 add(int index,Obj e) 方
法,就能夠指定當前對象在集合中的存放位置。一個對象能夠被反覆存儲進 List 中,
每調用一次 add 方法,這個對象就被插入進集合中一次,其實,並非把這個對象
自己存儲進了集合中,而是在集合中用一個索引變量指向這個對象,當這個對象被
add 屢次時,即至關於集合中有多個索引指向了這個對象,如圖 x 所示。List 除了
能夠以 Iterator 接口取得全部的元素,再逐一遍歷各個元素以外,還能夠調用
get(index i) 來明確說明取第幾個。函數
Map 與 List 和 Set 不一樣,它是雙列的集合,其中有 put 方法,定義以下:
put(obj key,obj value),每次存儲時,要存儲一對 key/value,不能存儲重複的
key,這個重複的規則也是按 equals 比較相等。取則能夠根據 key 得到相應的
value,即 get(Object key) 返回值爲 key 所對應的 value。另外,也能夠得到全部
的 key 的結合,還能夠得到全部的 value 的結合,還能夠得到 key 和 value 組合
成的 Map.Entry 對象的集合。性能
List 以特定次序來持有元素,可有重複元素。Set 沒法擁有重複元素, 內部排序。
Map 保存 key-value 值,value 可多值。
HashSet 按照 hashcode 值的某種運算方式進行存儲,而不是直接按 hashCode
值的大小進行存儲。例如,"abc" ---> 78,"def" ---> 62,"xyz" ---> 65 在hashSet 中的存儲順序不是 62,65,78,這些問題感謝之前一個叫崔健的學員提出,
最後經過查看源代碼給他解釋清楚,看本次培訓學員當中有多少能看懂源碼。
LinkedHashSet 按插入的順序存儲,那被存儲對象的 hashcode 方法還有什麼做用
呢?學員想一想! hashset 集合比較兩個對象是否相等,首先看 hashcode 方法是否相
等,而後看 equals 方法是否相等。new 兩個 Student 插入到 HashSet 中,看
HashSet 的 size,實現 hashcode 和 equals 方法後再看 size。
同一個對象能夠在 Vector 中加入屢次。往集合裏面加元素,至關於集合裏用一根繩
子鏈接到了目標對象。往 HashSet 中卻加不了屢次的。
Set 裏的元素是不能重複的,元素重複與否是使用 equals() 方法進行判斷的。
equals() 和 == 方法決定引用值是否指向同一對象 equals() 在類中被覆蓋,爲的是
當兩個分離的對象的內容和類型相配的話,返回真值。
兩個對象值相同 (x.equals(y) == true),但卻可有不一樣的 hash code,這句話對不對?
對。若是對象要保存在 HashSet 或 HashMap 中,它們的 equals 相等,那麼,它
們的 hashcode 值就必須相等。
若是不是要保存在 HashSet 或 HashMap,則與 hashcode 沒有什麼關係了,這時
候 hashcode 不等是能夠的,例如 arrayList 存儲的對象就不用實現 hashcode,當
然,咱們沒有理由不實現,一般都會去實現的。
heap 和 stack 有什麼區別。
Java 的內存分爲兩類,一類是棧內存,一類是堆內存。棧內存是指程序進入一個方法
時,會爲這個方法單獨分配一塊私屬存儲空間,用於存儲這個方法內部的局部變量,
當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。
堆是與棧做用不一樣的內存,通常用於存放不放在當前方法棧中的那些數據,例如,使
用 new 建立的對象都放在堆裏,因此,它不會隨方法的結束而消失。方法中的局部
變量使用 final 修飾後,放在堆中,而不是棧中。