前言無論是從事Javaee開發(fā)或者是Android開發(fā),JDK的基礎(chǔ)知識(shí)都尤為重要。我們?cè)诖a里經(jīng)常使用ArrayList、HashMap等,但卻很少思考為什么是使用它,使用的時(shí)候需要注意什么。甚至有可能去面試的時(shí)候,人家一問HashMap的實(shí)現(xiàn)原理,但卻只知道put和get,非常尷尬。 所以為了開發(fā)更高質(zhì)量的程序,寫出更優(yōu)秀的代碼,還是需要好好研究一下JDK的一些關(guān)鍵源碼。本文主要對(duì)JDK進(jìn)行一些重要的的知識(shí)的梳理及整理,便于學(xué)習(xí)及復(fù)習(xí)。 基礎(chǔ)知識(shí)基礎(chǔ)數(shù)據(jù)類型 變量就是申請(qǐng)內(nèi)存來存儲(chǔ)值。也就是說,當(dāng)創(chuàng)建變量的時(shí)候,需要在內(nèi)存中申請(qǐng)空間。 內(nèi)存管理系統(tǒng)根據(jù)變量的類型為變量分配存儲(chǔ)空間,分配的空間只能用來儲(chǔ)存該類型數(shù)據(jù) equal hashcode ==的區(qū)別 hashCode 方法的常規(guī)協(xié)定,該協(xié)定聲明相等對(duì)象必須具有相等的哈希碼。當(dāng)equals方法被重寫時(shí),通常有必要重寫 hashCode 方法。但hashCode相等,不一定equals() String、StringBuffer與StringBuilder的區(qū)別。 Java 平臺(tái)提供了兩種類型的字符串:String和StringBuffer / StringBuilder,它們可以儲(chǔ)存和操作字符串。其中String是只讀字符串,也就意味著String引用的字符串內(nèi)容是不能被改變的。而StringBuffer和StringBulder類表示的字符串對(duì)象可以直接進(jìn)行修改。StringBuilder是JDK1.5引入的,它和StringBuffer的方法完全相同,區(qū)別在于它是單線程環(huán)境下使用的,因?yàn)樗乃蟹矫娑紱]有被synchronized修飾,因此它的效率也比StringBuffer略高。 Java的四種引用,強(qiáng)弱軟虛,用到的場(chǎng)景。JDK1.2之前只有強(qiáng)引用,其他幾種引用都是在JDK1.2之后引入的. 強(qiáng)引用(Strong Reference) 最常用的引用類型,如Object obj = new Object(); 。只要強(qiáng)引用存在則GC時(shí)則必定不被回收。 軟引用(Soft Reference) 用于描述還有用但非必須的對(duì)象,當(dāng)堆將發(fā)生OOM(Out Of Memory)時(shí)則會(huì)回收軟引用所指向的內(nèi)存空間,若回收后依然空間不足才會(huì)拋出OOM。一般用于實(shí)現(xiàn)內(nèi)存敏感的高速緩存。 當(dāng)真正對(duì)象被標(biāo)記finalizable以及的finalize()方法調(diào)用之后并且內(nèi)存已經(jīng)清理, 那么如果SoftReference object還存在就被加入到它的 ReferenceQueue.只有前面幾步完成后,Soft Reference和Weak Reference的get方法才會(huì)返回null 弱引用(Weak Reference) 發(fā)生GC時(shí)必定回收弱引用指向的內(nèi)存空間。 和軟引用加入隊(duì)列的時(shí)機(jī)相同 虛引用(Phantom Reference) 又稱為幽靈引用或幻影引用,虛引用既不會(huì)影響對(duì)象的生命周期,也無法通過虛引用來獲取對(duì)象實(shí)例,僅用于在發(fā)生GC時(shí)接收一個(gè)系統(tǒng)通知。 當(dāng)一個(gè)對(duì)象的finalize方法已經(jīng)被調(diào)用了之后,這個(gè)對(duì)象的幽靈引用會(huì)被加入到隊(duì)列中。通過檢查該隊(duì)列里面的內(nèi)容就知道一個(gè)對(duì)象是不是已經(jīng)準(zhǔn)備要被回收了. 虛引用和軟引用和弱引用都不同,它會(huì)在內(nèi)存沒有清理的時(shí)候被加入引用隊(duì)列.虛引用的建立必須要傳入引用隊(duì)列,其他可以沒有 Java集合框架Collection是List、Set等集合高度抽象出來的接口,它包含了這些集合的基本操作,它主要又分為兩大部分:List和Set。 List接口通常表示一個(gè)列表(數(shù)組、隊(duì)列、鏈表、棧等),其中的元素可以重復(fù),常用實(shí)現(xiàn)類為ArrayList和LinkedList,另外還有不常用的Vector。另外,LinkedList還是實(shí)現(xiàn)了Queue接口,因此也可以作為隊(duì)列使用。 Set接口通常表示一個(gè)集合,其中的元素不允許重復(fù)(通過hashcode和equals函數(shù)保證),常用實(shí)現(xiàn)類有HashSet和TreeSet,HashSet是通過Map中的HashMap實(shí)現(xiàn)的,而TreeSet是通過Map中的TreeMap實(shí)現(xiàn)的。另外,TreeSet還實(shí)現(xiàn)了SortedSet接口,因此是有序的集合(集合中的元素要實(shí)現(xiàn)Comparable接口,并覆寫Compartor函數(shù)才行)。 我們看到,抽象類AbstractCollection、AbstractList和AbstractSet分別實(shí)現(xiàn)了Collection、List和Set接口,這就是在Java集合框架中用的很多的適配器設(shè)計(jì)模式,用這些抽象類去實(shí)現(xiàn)接口,在抽象類中實(shí)現(xiàn)接口中的若干或全部方法,這樣下面的一些類只需直接繼承該抽象類,并實(shí)現(xiàn)自己需要的方法即可,而不用實(shí)現(xiàn)接口中的全部抽象方法。 Map是一個(gè)映射接口,其中的每個(gè)元素都是一個(gè)key-value鍵值對(duì),同樣抽象類AbstractMap通過適配器模式實(shí)現(xiàn)了Map接口中的大部分函數(shù),TreeMap、HashMap、WeakHashMap等實(shí)現(xiàn)類都通過繼承AbstractMap來實(shí)現(xiàn),另外,不常用的HashTable直接實(shí)現(xiàn)了Map接口,它和Vector都是JDK1.0就引入的集合類。 Iterator是遍歷集合的迭代器(不能遍歷Map,只用來遍歷Collection),Collection的實(shí)現(xiàn)類都實(shí)現(xiàn)了iterator()函數(shù),它返回一個(gè)Iterator對(duì)象,用來遍歷集合,ListIterator則專門用來遍歷List。而Enumeration則是JDK1.0時(shí)引入的,作用與Iterator相同,但它的功能比Iterator要少,它只能再Hashtable、Vector和Stack中使用。 Arrays和Collections是用來操作數(shù)組、集合的兩個(gè)工具類,例如在ArrayList和Vector中大量調(diào)用了Arrays.Copyof()方法,而Collections中有很多靜態(tài)方法可以返回各集合類的synchronized版本,即線程安全的版本,當(dāng)然了,如果要用線程安全的結(jié)合類,首選Concurrent并發(fā)包下的對(duì)應(yīng)的集合類。 Collection List Set Map 區(qū)別 常用集合分析 因?yàn)橐沛溄铀源蠹艺?qǐng)看原文 并發(fā) Lists
CopyOnWriteArrayList——幾乎不更新,常用來遍歷 Queues / deques
Maps
Sets
總結(jié) Set的選擇
List 選擇
Map 的選擇
|
|
|