摘要:而在集合中,值僅僅是一個對象罷了該對象對本身而言是無用的。將這篇文章作為集合的總結篇,但覺得沒什么好寫就回答一些面試題去了,找了一會面試題又覺得不夠系統。
前言
聲明,本文用的是jdk1.8
花了一個星期,把Java容器核心的知識過了一遍,感覺集合已經無所畏懼了!!(哈哈哈....),現在來總結一下吧~~
回顧目錄:
Collection總覽
List集合就這么簡單【源碼剖析】
Map集合、散列表、紅黑樹介紹
HashMap就是這么簡單【源碼剖析】
LinkedHashMap就這么簡單【源碼剖析】
TreeMap就這么簡單【源碼剖析】
ConcurrentHashMap基于JDK1.8源碼剖析
Set集合就這么簡單!
Java容器可分為兩大類:
Collection
List
ArrayList
LinkedList
Vector(了解,已過時)
Set
HashSet
LinkedHashSet
TreeSet
Map
HashMap
LinkedHashMap
TreeMap
ConcurrentHashMap
Hashtable(了解,,已過時)
著重標出的那些就是我們用得最多的容器。
其實,我也不知道要怎么總結好,因為之前寫每一篇的時候都總結過了。現在又把他們重新羅列出來好像有點水,所以,我決定去回答一些Java容器的面試題!
當然了,我的答案未必就是正確的。如果有錯誤的地方大家多多包含,希望不吝在評論區留言指正~~
一、ArrayList和Vector的區別共同點:
這兩個類都實現了List接口,它們都是有序的集合(存儲有序),底層是數組。我們可以按位置索引號取出某個元素,允許元素重復和為null。
區別:
同步性:
ArrayList是非同步的
Vector是同步的
即便需要同步的時候,我們可以使用Collections工具類來構建出同步的ArrayList而不用Vector
擴容大小:
Vector增長原來的一倍,ArrayList增長原來的0.5倍
二、HashMap和Hashtable的區別共同點:
從存儲結構和實現來講基本上都是相同的,都是實現Map接口~
區別:
同步性:
HashMap是非同步的
Hashtable是同步的
需要同步的時候,我們往往不使用,而使用ConcurrentHashMapConcurrentHashMap基于JDK1.8源碼剖析
是否允許為null:
HashMap允許為null
Hashtable不允許為null
contains方法
這知識點是在牛客網刷到的,沒想到這種題還會有(我不太喜歡)....
Hashtable有contains方法
HashMap把Hashtable的contains方法去掉了,改成了containsValue和containsKey
繼承不同:
HashMap
public class Hashtable
共同點:
都是Java常用的容器,都是接口(ps:寫出來感覺好像和沒寫一樣.....)
不同點:
存儲結構不同:
List是存儲單列的集合
Map存儲的是key-value鍵值對的集合
元素是否可重復:
List允許元素重復
Map不允許key重復
是否有序:
List集合是有序的(存儲有序)
Map集合是無序的(存儲無序)
四、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()方法都有使用!
五、Collection和Collections的區別Collection是集合的上級接口,繼承它的有Set和List接口
Collections是集合的工具類,提供了一系列的靜態方法對集合的搜索、查找、同步等操作
六、說出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要快。(我測試過)
七、Enumeration和Iterator接口的區別這個我在前面的文章中也沒有詳細去講它們,只是大概知道的是:Iterator替代了Enumeration,Enumeration是一個舊的迭代器了。
與Enumeration相比,Iterator更加安全,因為當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。
我們在做練習的時候,迭代時會不會經常出錯,拋出ConcurrentModificationException異常,說我們在遍歷的時候還在修改元素。
這其實就是fail-fast機制~具體可參考博文:https://blog.csdn.net/panweiwei1994/article/details/77051261
區別有三點:
Iterator的方法名比Enumeration更科學
Iterator有fail-fast機制,比Enumeration更安全
Iterator能夠刪除元素,Enumeration并不能刪除元素
八、ListIterator有什么特點ListIterator繼承了Iterator接口,它用于遍歷List集合的元素。
ListIterator可以實現雙向遍歷,添加元素,設置元素
看一下源碼的方法就知道了:
九、并發集合類是什么?Java1.5并發包(java.util.concurrent)包含線程安全集合類,允許在迭代時修改集合。
迭代器被設計為fail-fast的,會拋出ConcurrentModificationException。
一部分類為:
CopyOnWriteArrayList
ConcurrentHashMap
CopyOnWriteArraySet
十、Java中HashMap的key值要是為類對象則該類需要滿足什么條件?需要同時重寫該類的hashCode()方法和它的equals()方法。
從源碼可以得知,在插入元素的時候是先算出該對象的hashCode。如果hashcode相等話的。那么表明該對象是存儲在同一個位置上的。
如果調用equals()方法,兩個key相同,則替換元素
如果調用equals()方法,兩個key不相同,則說明該hashCode僅僅是碰巧相同,此時是散列沖突,將新增的元素放在桶子上
一般來說,我們會認為:只要兩個對象的成員變量的值是相等的,那么我們就認為這兩個對象是相等的!因為,Object底層比較的是兩個對象的地址,而對我們開發來說這樣的意義并不大~這也就為什么我們要重寫equals()方法
重寫了equals()方法,就要重寫hashCode()的方法。因為equals()認定了這兩個對象相同,而同一個對象調用hashCode()方法時,是應該返回相同的值的!
十一、與Java集合框架相關的有哪些最好的實踐根據需要確定集合的類型。如果是單列的集合,我們考慮用Collection下的子接口ArrayList和Set。如果是映射,我們就考慮使用Map~
確定完我們的集合類型,我們接下來確定使用該集合類型下的哪個子類~我認為可以簡單分成幾個步驟:
是否需要同步
去找線程安全的集合類使用
迭代時是否需要有序(插入順序有序)
去找Linked雙向列表結構的
是否需要排序(自然順序或者手動排序)
去找Tree紅黑樹類型的(JDK1.8)
估算存放集合的數據量有多大,無論是List還是Map,它們實現動態增長,都是有性能消耗的。在初始集合的時候給出一個合理的容量會減少動態增長時的消耗~
使用泛型,避免在運行時出現ClassCastException
盡可能使用Collections工具類,或者獲取只讀、同步或空的集合,而非編寫自己的實現。它將會提供代碼重用性,它有著更好的穩定性和可維護性
十二、ArrayList集合加入1萬條數據,應該怎么提高效率ArrayList的默認初始容量為10,要插入大量數據的時候需要不斷擴容,而擴容是非常影響性能的。因此,現在明確了10萬條數據了,我們可以直接在初始化的時候就設置ArrayList的容量!
這樣就可以提高效率了~
十三、總結2018年4月15日17:14:03,上面找了一些面試題答了一下,感覺不夠過癮呀。很多我覺得比較重要的知識點我都沒有找到對應的面試題(可能我搜索的能力太水了?)。
將這篇文章作為集合的總結篇,但覺得沒什么好寫就回答一些面試題去了,找了一會面試題又覺得不夠系統。而這篇總結我又不想復制前面的章節總結到這里來。于是我決定畫一個腦圖來結束這篇文章!
2018年4月15日19:31:33 畫完啦!!!!!
需要更多腦圖的同學可關注公眾號:Java3y,回復【腦圖】即可~
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y。為了大家方便,剛新建了一下qq群:742919422,大家也可以去交流交流。謝謝支持了!希望能多介紹給其他有需要的朋友
文章的目錄導航:https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang
目前初步打算寫多線程,你們覺得怎么樣呢?可以在評論區留言~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69090.html
摘要:我在面試前針對基礎也花了不少的時間,期間也將自己寫過的博文粗略地刷了一遍,同時也在網上找了不少比較好的資料部分是沒看完的。看面試題也是校驗自己是否真正理解了這個知識點,也很有可能會有新的收獲。 一、前言 只有光頭才能變強 回顧前面: 廣州三本找Java實習經歷 上一篇寫了自己面試的經歷和一些在面試的時候遇到的題目(筆試題和面試題)。 我在面試前針對Java基礎也花了不少的時間,期間也將...
摘要:系統級線程核心級線程由操作系統內核進行管理。值得注意的是多線程的存在,不是提高程序的執行速度。實現多線程上面說了一大堆基礎,理解完的話。虛擬機的啟動是單線程的還是多線程的是多線程的。 前言 之前花了一個星期回顧了Java集合: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼剖析】 LinkedHashMa...
摘要:使用的好處知乎的回答不用自己組裝,拿來就用。統一配置,便于修改。 前言 只有光頭才能變強 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡單啦 單例模式你會幾種寫法? 工廠模式理解了沒有? 在刷Spring書籍的時候花了點時間去學習了單例模式和工廠模式,總的來說還是非常值得的! 本來想的是刷完《Spring 實戰 (第4版)》和《精通Spring4.x 企業應用開發實戰》...
摘要:的重要性毋庸置疑,可以毫不夸張的說虛擬機是整個平臺的基石。方面的知識,也一直是等大廠面試考核的重點。本專欄將分為如下幾個大模塊進行分析開篇介紹運行時數據區。最主要的是讓我知道能得到多少小伙伴的認可,畢竟大家的認可,就是不懈努力的動力 JVM的重要性毋庸置疑,可以毫不夸張的說Java虛擬機是整個Java平臺的基石。 JVM方面的知識,也一直是BAT等大廠面試考核的重點。特別是JVM調優,...
摘要:開啟自動配置功能后文詳解這個注解,學過的同學應該對它不會陌生,就是掃描注解,默認是掃描當前類下的。簡單來說,這個注解可以幫助我們自動載入應用程序所需要的所有默認配置。簡單理解這二者掃描的對象是不一樣的。 前言 只有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y 回顧前面Spring的文章(以學習...
閱讀 2137·2023-04-26 00:23
閱讀 807·2021-09-08 09:45
閱讀 2435·2019-08-28 18:20
閱讀 2542·2019-08-26 13:51
閱讀 1595·2019-08-26 10:32
閱讀 1392·2019-08-26 10:24
閱讀 2027·2019-08-26 10:23
閱讀 2196·2019-08-23 18:10