校招面試之Java容器

最近校招季材鹦,特把自己面試中遇到的問(wèn)題整理整理逝淹,以鞏固自己的知識(shí)。

Java中對(duì)于容器有兩大類存儲(chǔ)方式桶唐,一種是單元素存放创橄,還有一種就是key-value這種有關(guān)聯(lián)的雙元素存放了。對(duì)于Java中的容器莽红,有下列的結(jié)構(gòu)圖可以參照:

Collection (用來(lái)存放獨(dú)立元素的序列)
├List 
│├LinkedList 
│├ArrayList 
│└Vector 
│ └Stack 
└Set 
 ├HashSet
 └TreeSet
Map (用來(lái)存放key-value型的元素對(duì))
├Hashtable 
├HashMap 
├TreeMap 
└WeakHashMap

下面妥畏,我們就來(lái)分別講講這幾種容器。

List

List是有序的Collection安吁,使用此接口能控制每個(gè)元素插入的位置醉蚁,用戶能夠使用索引來(lái)訪問(wèn)元素。與Set不同的是鬼店,List允許有重復(fù)的元素在其中网棍。

  • ArrayList
    ArrayList相當(dāng)于順式存儲(chǔ)(線性表),當(dāng)實(shí)例化一個(gè)ArrayList時(shí)妇智,一個(gè)數(shù)組也被實(shí)例化了滥玷,默認(rèn)初始化一個(gè)長(zhǎng)度為10的數(shù)組氏身。當(dāng)添加數(shù)據(jù)的時(shí)候會(huì)判斷當(dāng)前容量是否能夠容下新增的對(duì)象,一旦發(fā)現(xiàn)容量不足惑畴,會(huì)自動(dòng)擴(kuò)容蛋欣,新的大小為原有容量的1.5倍+1。

    ArrayList可以快速隨機(jī)訪問(wèn)如贷,通過(guò)調(diào)用get(i)方法來(lái)訪問(wèn)下標(biāo)為i的元素陷虎。

  • LindedList
    LinkedList相當(dāng)于鏈?zhǔn)酱鎯?chǔ)(雙向鏈表),它是通過(guò)節(jié)點(diǎn)直接彼此連接來(lái)實(shí)現(xiàn)的杠袱。每一個(gè)節(jié)點(diǎn)都包括前一個(gè)節(jié)點(diǎn)的引用尚猿,后一個(gè)節(jié)點(diǎn)的引用和節(jié)點(diǎn)存儲(chǔ)的值。
    當(dāng)插入或刪除節(jié)點(diǎn)時(shí)楣富,只需要修改其中保持先后關(guān)系的節(jié)點(diǎn)的引用即可凿掂,所以,操作其中的對(duì)象速度比ArrayList要快的多纹蝴。

    但是LinkedList不能隨機(jī)訪問(wèn)元素缠劝,雖然它有g(shù)et()方法,但是這個(gè)方法是通過(guò)遍歷節(jié)點(diǎn)來(lái)定位的骗灶,速度很慢惨恭。

  • Vector

    Vector和ArrayList一樣,也是用數(shù)組來(lái)存儲(chǔ)元素耙旦。但是Vector使用了synchronized方法脱羡,線程安全,所以在性能上比ArrayList要差免都。

ArrayList和LinkedList的區(qū)別

  • ArrayList實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)锉罐,LinkedList實(shí)現(xiàn)了基于鏈表的數(shù)據(jù)結(jié)構(gòu)
  • 對(duì)于隨機(jī)訪問(wèn)get和set,ArrayList優(yōu)于LinkedList
  • 對(duì)于增刪add和remove绕娘,LinkedList優(yōu)于ArrayList

Set

Set是一種不包含重復(fù)元素的Collection脓规,它的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素险领。

  • HashSet
    HashSet實(shí)現(xiàn)了Set接口侨舆,由哈希表支持。它不保證Set的迭代順序绢陌,特別是它不保證該順序恒久不變挨下。

    HashSet底層使用的容器實(shí)際上就是HashMap,它以HashMap的key來(lái)保存所有的元素脐湾,value使用一個(gè)static final的Object對(duì)象來(lái)標(biāo)識(shí)臭笆。

    private static final Object PRESENT = new Object();
    
  • TreeSet
    TreeSet整體上性能沒(méi)有HashSet好,但是它可以維持元素的排序狀態(tài)。

    TreeSet底層使用的容器實(shí)際上就是TreeMap愁铺,它以TreeMap的key來(lái)保存set集合的元素鹰霍,value都以一個(gè)名為PRESENT的Object對(duì)象代替(無(wú)實(shí)際意義)。

Map

Map接口提供key到value的映射茵乱,一個(gè)Map不能包含相同的key茂洒,每個(gè)key只能映射一個(gè)value。

  • HashMap
    HashMap底層就是一個(gè)數(shù)組結(jié)構(gòu)似将,數(shù)組中的每一項(xiàng)又是一個(gè)鏈表(其實(shí)就是哈希表的拉鏈法實(shí)現(xiàn))获黔。但是此類不保證映射的順序蚀苛,特別是不保證該順序恒久不變在验。但是TreeMap可以維持映射的順序。

  • Hashtable
    和HashMap實(shí)現(xiàn)差不多堵未,具體區(qū)別見(jiàn)下面的Hashtable和HashMap的區(qū)別腋舌。

  • TreeMap
    TreeMap的底層實(shí)現(xiàn)是一個(gè)紅黑樹(shù)結(jié)構(gòu),這樣可以保證快速檢索節(jié)點(diǎn)渗蟹,TreeMap可以維持映射的順序块饺。

    下面我們來(lái)具體說(shuō)下TreeMap的底層實(shí)現(xiàn),首先我們需要了解下排序二叉樹(shù):

    • 排序二叉樹(shù):要么是一棵空二叉樹(shù)雌芽,要么是具有下列性質(zhì)的二叉樹(shù):
      1. 若它的左子樹(shù)不為空授艰,則左子樹(shù)上所有節(jié)點(diǎn)的值均小于根節(jié)點(diǎn)的值
      2. 若它的右子樹(shù)不為空,則右子樹(shù)上所有節(jié)點(diǎn)的值均大于根節(jié)點(diǎn)的值
      3. 它的左右自子樹(shù)也分別為排序二叉樹(shù)

    對(duì)于排序二叉樹(shù)世落,它的中序遍歷就可以得到由小到大的有序序列淮腾,所以用它就可以實(shí)現(xiàn)快速檢索,但是為什么Java還要多此一舉用紅黑樹(shù)呢屉佳?

    • 排序二叉樹(shù)雖然可以快速檢索谷朝,但是在最壞情況下:若插入的節(jié)點(diǎn)本身就是有序的,要么由小到大排列武花,要么由大到小排列圆凰,那么最后得到的排序二叉樹(shù)就變?yōu)榱随湵恚核械墓?jié)點(diǎn)只有左節(jié)點(diǎn)或者所有的節(jié)點(diǎn)只有右節(jié)點(diǎn)。這種情況下体箕,排序二叉樹(shù)就變?yōu)榱似胀ㄦ湵碜ǘぃ瑱z索效率會(huì)很差。

    所以累铅,Java引入了紅黑樹(shù)作為TreeMap的底層實(shí)現(xiàn)

    • 紅黑樹(shù):紅黑樹(shù)是一種更高效的檢索二叉樹(shù)驶沼,它的性質(zhì)為:

      1. 所有的節(jié)點(diǎn)都為紅色或者黑色
      2. 根節(jié)點(diǎn)永遠(yuǎn)是黑色
      3. 所有的葉節(jié)點(diǎn)都是空節(jié)點(diǎn)(NULL),并且是黑色
      4. 每個(gè)紅色節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)都是黑色争群,即從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)的路徑上不會(huì)出現(xiàn)兩個(gè)連續(xù)的紅色節(jié)點(diǎn)回怜。
      5. 從任一節(jié)點(diǎn)到其子樹(shù)中每個(gè)葉子節(jié)點(diǎn)的路徑都包含相同數(shù)量的黑色節(jié)點(diǎn)

      紅黑樹(shù)通過(guò)上面的限制來(lái)保證它大致是平衡的(因?yàn)榧t黑樹(shù)的高度不會(huì)無(wú)限增高),這樣保證了紅黑樹(shù)在最壞情況下都是高效的,不會(huì)出現(xiàn)普通排序二叉樹(shù)的情況玉雾。

Hashtable和HashMap的區(qū)別

  • 繼承和實(shí)現(xiàn)不同
    Hashtable是繼承自陳舊的Dictionary類翔试,實(shí)現(xiàn)了Map接口;HashMap實(shí)現(xiàn)接口(繼承自AbstractMap复旬,AbstractMap實(shí)現(xiàn)Map接口)

  • 線程安全不同
    Hashtable是線程安全的垦缅,它的實(shí)現(xiàn)方法里面都添加了synchronized關(guān)鍵字來(lái)確保線程同步。HashMap是線程不安全的驹碍,在多線程編程下如使用HashMap需要使用Collections.synchronizedMap()來(lái)獲取一個(gè)線程安全的集合壁涎。

  • 對(duì)null的處理不同
    HashMap支持null作為key和value,但是Hashtable不允許(key志秃,value都不允許)怔球。HashMap的方法get()返回null時(shí),既可以表示沒(méi)有改鍵浮还,也可以表示該鍵對(duì)應(yīng)的值為null竟坛,所以不能用此判斷是否有該鍵,而應(yīng)該用containsKey()钧舌。

  • HashMap初始容量為16担汤,Hashtable初始容量為11。HashMap擴(kuò)容時(shí)是當(dāng)前容量翻倍:capacity2洼冻,Hashtable是當(dāng)前容量翻倍+1:capacity2+1崭歧。

  • 哈希值的使用不同
    Hashtable直接使用key的hashcode對(duì)table數(shù)組的長(zhǎng)度取模,HashMap是對(duì)key的hashcode進(jìn)行二次hash撞牢,然后對(duì)table數(shù)組的長(zhǎng)度取模率碾,以獲得更好的散列值。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末普泡,一起剝皮案震驚了整個(gè)濱河市播掷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撼班,老刑警劉巖歧匈,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異砰嘁,居然都是意外死亡件炉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門矮湘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)斟冕,“玉大人,你說(shuō)我怎么就攤上這事缅阳】纳撸” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秀撇。 經(jīng)常有香客問(wèn)我超棺,道長(zhǎng),這世上最難降的妖魔是什么呵燕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任棠绘,我火速辦了婚禮,結(jié)果婚禮上再扭,老公的妹妹穿的比我還像新娘氧苍。我一直安慰自己,他們只是感情好泛范,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布让虐。 她就那樣靜靜地躺著,像睡著了一般敦跌。 火紅的嫁衣襯著肌膚如雪澄干。 梳的紋絲不亂的頭發(fā)上逛揩,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天柠傍,我揣著相機(jī)與錄音,去河邊找鬼辩稽。 笑死惧笛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逞泄。 我是一名探鬼主播患整,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼喷众!你這毒婦竟也來(lái)了各谚?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤到千,失蹤者是張志新(化名)和其女友劉穎昌渤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體憔四,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膀息,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了了赵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片潜支。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柿汛,靈堂內(nèi)的尸體忽然破棺而出冗酿,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布裁替,位于F島的核電站鸠窗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胯究。R本人自食惡果不足惜稍计,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裕循。 院中可真熱鬧臣嚣,春花似錦、人聲如沸剥哑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)株婴。三九已至怎虫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間困介,已是汗流浹背大审。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留座哩,地道東北人徒扶。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像根穷,于是被迫代替她去往敵國(guó)和親姜骡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容