前言
聲明,本文用的是jdk1.8java
花了一個星期,把Java容器核心的知識過了一遍,感受集合已經無所畏懼了!!(哈哈哈....),如今來總結一下吧~~面試
回顧目錄:數組
Java容器可分爲兩大類:安全
- Collection
- List
- ArrayList
- LinkedList
- Vector(瞭解,已過期)
- Set
- Map
- HashMap
- TreeMap
- ConcurrentHashMap
- Hashtable(瞭解,,已過期)
着重標出的那些就是咱們用得最多的容器。微信
其實,我也不知道要怎麼總結好,由於以前寫每一篇的時候都總結過了。如今又把他們從新羅列出來好像有點水,因此,我決定去回答一些Java容器的面試題!多線程
固然了,個人答案未必就是正確的。若是有錯誤的地方你們多多包含,但願不吝在評論區留言指正~~併發
1、ArrayList和Vector的區別
共同點:app
- 這兩個類都實現了List接口,它們都是有序的集合(存儲有序),底層是數組。咱們能夠按位置索引號取出某個元素,容許元素重複和爲null。
區別:框架
- 同步性:
- ArrayList是非同步的
- Vector是同步的
- 即使須要同步的時候,咱們可使用Collections工具類來構建出同步的ArrayList而不用Vector
- 擴容大小:
- Vector增加原來的一倍,ArrayList增加原來的0.5倍
2、HashMap和Hashtable的區別
共同點:工具
- 從存儲結構和實現來說基本上都是相同的,都是實現Map接口~
區別:
- 同步性:
- 是否容許爲null:
- HashMap容許爲null
- Hashtable不容許爲null
- contains方法
- 這知識點是在牛客網刷到的,沒想到這種題還會有(我不太喜歡)....
- Hashtable有contains方法
- HashMap把Hashtable的contains方法去掉了,改爲了containsValue和containsKey
- 繼承不一樣:
- HashMap<K,V> extends AbstractMap<K,V>
- public class Hashtable<K,V> extends Dictionary<K,V>
3、List和Map的區別
共同點:
- 都是Java經常使用的容器,都是接口(ps:寫出來感受好像和沒寫同樣.....)
不一樣點:
- 存儲結構不一樣:
- List是存儲單列的集合
- Map存儲的是key-value鍵值對的集合
- 元素是否可重複:
- 是否有序:
- List集合是有序的(存儲有序)
- Map集合是無序的(存儲無序)
4、Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==仍是equals()?
咱們知道Set集合實際大都使用的是Map集合的put方法來添加元素。
以HashSet爲例,HashSet裏的元素不能重複,在源碼(HashMap)是這樣體現的:
// 1. 若是key 相等
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
// 2. 修改對應的value
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
添加元素的時候,若是key(也對應的Set集合的元素)相等,那麼則修改value值。而在Set集合中,value值僅僅是一個Object對象罷了(該對象對Set自己而言是無用的)。
也就是說:Set集合若是添加的元素相同時,是根本沒有插入的(僅修改了一個無用的value值)!從源碼(HashMap)中也看出來,==和equals()方法都有使用!
5、Collection和Collections的區別
- Collection是集合的上級接口,繼承它的有Set和List接口
- Collections是集合的工具類,提供了一系列的靜態方法對集合的搜索、查找、同步等操做
6、說出ArrayList,LinkedList的存儲性能和特性
ArrayList的底層是數組,LinkedList的底層是雙向鏈表。
- ArrayList它支持以角標位置進行索引出對應的元素(隨機訪問),而LinkedList則須要遍歷整個鏈表來獲取對應的元素。所以通常來講ArrayList的訪問速度是要比LinkedList要快的
- ArrayList因爲是數組,對於刪除和修改而言消耗是比較大(複製和移動數組實現),LinkedList是雙向鏈表刪除和修改只須要修改對應的指針便可,消耗是很小的。所以通常來講LinkedList的增刪速度是要比ArrayList要快的
6.1擴展:
ArrayList的增刪未必就是比LinkedList要慢。
- 若是增刪都是在末尾來操做【每次調用的都是remove()和add()】,此時ArrayList就不須要移動和複製數組來進行操做了。若是數據量有百萬級的時,速度是會比LinkedList要快的。(我測試過)
- 若是刪除操做的位置是在中間。因爲LinkedList的消耗主要是在遍歷上,ArrayList的消耗主要是在移動和複製上(底層調用的是arraycopy()方法,是native方法)。
- LinkedList的遍歷速度是要慢於ArrayList的複製移動速度的
- 若是數據量有百萬級的時,仍是ArrayList要快。(我測試過)
7、Enumeration和Iterator接口的區別
這個我在前面的文章中也沒有詳細去講它們,只是大概知道的是:Iterator替代了Enumeration,Enumeration是一箇舊的迭代器了。
與Enumeration相比,Iterator更加安全,由於當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。
區別有三點:
- Iterator的方法名比Enumeration更科學
- Iterator有fail-fast機制,比Enumeration更安全
- Iterator可以刪除元素,Enumeration並不能刪除元素
8、ListIterator有什麼特色
- ListIterator繼承了Iterator接口,它用於遍歷List集合的元素。
- ListIterator能夠實現雙向遍歷,添加元素,設置元素
看一下源碼的方法就知道了:
9、併發集合類是什麼?
Java1.5併發包(java.util.concurrent)包含線程安全集合類,容許在迭代時修改集合。
- 迭代器被設計爲fail-fast的,會拋出ConcurrentModificationException。
- 一部分類爲:
- CopyOnWriteArrayList
- ConcurrentHashMap
- CopyOnWriteArraySet
10、Java中HashMap的key值要是爲類對象則該類須要知足什麼條件?
須要同時重寫該類的hashCode()方法和它的equals()方法。
- 從源碼能夠得知,在插入元素的時候是先算出該對象的hashCode。若是hashcode相等話的。那麼代表該對象是存儲在同一個位置上的。
- 若是調用equals()方法,兩個key相同,則替換元素
- 若是調用equals()方法,兩個key不相同,則說明該hashCode僅僅是碰巧相同,此時是散列衝突,將新增的元素放在桶子上
通常來講,咱們會認爲:只要兩個對象的成員變量的值是相等的,那麼咱們就認爲這兩個對象是相等的!由於,Object底層比較的是兩個對象的地址,而對咱們開發來講這樣的意義並不大~這也就爲何咱們要重寫equals()
方法
重寫了equals()方法,就要重寫hashCode()的方法。由於equals()認定了這兩個對象相同,而同一個對象調用hashCode()方法時,是應該返回相同的值的!
11、與Java集合框架相關的有哪些最好的實踐
- 根據須要肯定集合的類型。若是是單列的集合,咱們考慮用Collection下的子接口ArrayList和Set。若是是映射,咱們就考慮使用Map~
- 肯定完咱們的集合類型,咱們接下來肯定使用該集合類型下的哪一個子類~我認爲能夠簡單分紅幾個步驟:
- 是否須要同步
- 迭代時是否須要有序(插入順序有序)
- 是否須要排序(天然順序或者手動排序)
- 估算存放集合的數據量有多大,不管是List仍是Map,它們實現動態增加,都是有性能消耗的。在初始集合的時候給出一個合理的容量會減小動態增加時的消耗~
- 使用泛型,避免在運行時出現ClassCastException
- 儘量使用Collections工具類,或者獲取只讀、同步或空的集合,而非編寫本身的實現。它將會提供代碼重用性,它有着更好的穩定性和可維護性
12、ArrayList集合加入1萬條數據,應該怎麼提升效率
ArrayList的默認初始容量爲10,要插入大量數據的時候須要不斷擴容,而擴容是很是影響性能的。所以,如今明確了10萬條數據了,咱們能夠直接在初始化的時候就設置ArrayList的容量!
這樣就能夠提升效率了~
十3、總結
2018年4月15日17:14:03,上面找了一些面試題答了一下,感受不夠過癮呀。不少我以爲比較重要的知識點我都沒有找到對應的面試題(可能我搜索的能力太水了?)。
將這篇文章做爲集合的總結篇,但以爲沒什麼好寫就回答一些面試題去了,找了一會面試題又以爲不夠系統。而這篇總結我又不想複製前面的章節總結到這裏來。因而我決定畫一個腦圖來結束這篇文章!
2018年4月15日19:31:33 畫完啦!!!!!
須要更多腦圖的同窗可關注公衆號:Java3y,回覆【腦圖】便可~
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y。謝謝支持了!但願能多介紹給其餘有須要的朋友
文章的目錄導航:zhongfucheng.bitcron.com/post/shou-j…
目前初步打算寫多線程,大家以爲怎麼樣呢?能夠在評論區留言~