电竞比分网-中国电竞赛事及体育赛事平台

分享

你應(yīng)該知道的JDK知識(shí)

 諤諤熱 2017-09-17

前言

無論是從事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í)。

你應(yīng)該知道的JDK知識(shí)

基礎(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ù)

你應(yīng)該知道的JDK知識(shí)

equal hashcode ==的區(qū)別

你應(yīng)該知道的JDK知識(shí)

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集合框架

你應(yīng)該知道的JDK知識(shí)

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īng)該知道的JDK知識(shí)

常用集合分析

因?yàn)橐沛溄铀源蠹艺?qǐng)看原文

你應(yīng)該知道的JDK知識(shí)

并發(fā)

Lists

  • ArrayList——基于泛型數(shù)組

  • LinkedList——不推薦使用

  • Vector——已廢棄(deprecated)

CopyOnWriteArrayList——幾乎不更新,常用來遍歷

Queues / deques

  • ArrayDeque——基于泛型數(shù)組

  • Stack——已廢棄(deprecated)

  • PriorityQueue——讀取操作的內(nèi)容已排序

  • ArrayBlockingQueue——帶邊界的阻塞式隊(duì)列

  • ConcurrentLinkedDeque / ConcurrentLinkedQueue——無邊界的鏈表隊(duì)列(CAS)

  • DelayQueue——元素帶有延遲的隊(duì)列

  • LinkedBlockingDeque / LinkedBlockingQueue——鏈表隊(duì)列(帶鎖),可設(shè)定是否帶邊界

  • LinkedTransferQueue——可將元素

    transfer

    進(jìn)行w/o存儲(chǔ)
  • PriorityBlockingQueue——并發(fā)PriorityQueue

  • SynchronousQueue——使用Queue接口進(jìn)行Exchanger

Maps

  • HashMap——通用Map

  • EnumMap——鍵使用enum

  • Hashtable——已廢棄(deprecated)

  • IdentityHashMap——鍵使用==進(jìn)行比較

  • LinkedHashMap——保持插入順序

  • TreeMap——鍵已排序

  • WeakHashMap——適用于緩存(cache)

  • ConcurrentHashMap——通用并發(fā)Map

  • ConcurrentSkipListMap——已排序的并發(fā)Map

Sets

  • HashSet——通用set

  • EnumSet——enum Set

  • BitSet——比特或密集的整數(shù)Set

  • LinkedHashSet——保持插入順序

  • TreeSet——排序Set

  • ConcurrentSkipListSet——排序并發(fā)Set

  • CopyOnWriteArraySet——幾乎不更新,通常只做遍歷

總結(jié)

Set的選擇

  1. HashSet的性能總是比TreeSet好(特別是最常用的添加、查詢?cè)氐炔僮?,因?yàn)門reeSet需要額外的紅黑樹算法來維護(hù)集合元素的次序。只有當(dāng)需要一個(gè)保持排序的Set時(shí),才應(yīng)該使用TreeSet,否則都應(yīng)該使用HashSet

  2. 對(duì)于普通的插入、刪除操作,LinkedHashSet比HashSet要略慢一點(diǎn),這是由維護(hù)鏈表所帶來的開銷造成的。不過,因?yàn)橛辛随湵淼拇嬖?,遍歷LinkedHashSet會(huì)更快

  3. EnumSet是所有Set實(shí)現(xiàn)類中性能最好的,但它只能保存同一個(gè)枚舉類的枚舉值作為集合元素

  4. HashSet、TreeSet、EnumSet都是'線程不安全'的,通??梢酝ㄟ^Collections工具類的synchronizedSortedSet方法來'包裝'該Set集合。

    SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));

List 選擇

  1. java提供的List就是一個(gè)'線性表接口',ArrayList(基于數(shù)組的線性表)、LinkedList(基于鏈的線性表)是線性表的兩種典型實(shí)現(xiàn)

  2. Queue代表了隊(duì)列,Deque代表了雙端隊(duì)列(既可以作為隊(duì)列使用、也可以作為棧使用)

  3. 因?yàn)閿?shù)組以一塊連續(xù)內(nèi)存來保存所有的數(shù)組元素,所以數(shù)組在隨機(jī)訪問時(shí)性能最好。所以的內(nèi)部以數(shù)組作為底層實(shí)現(xiàn)的集合在隨機(jī)訪問時(shí)性能最好。

  4. 內(nèi)部以鏈表作為底層實(shí)現(xiàn)的集合在執(zhí)行插入、刪除操作時(shí)有很好的性能

  5. 進(jìn)行迭代操作時(shí),以鏈表作為底層實(shí)現(xiàn)的集合比以數(shù)組作為底層實(shí)現(xiàn)的集合性能好

  6. 當(dāng)要大量的插入,刪除,應(yīng)當(dāng)選用LinkedList;當(dāng)需要快速隨機(jī)訪問則選用ArrayList;

Map 的選擇

  1. HashMap和Hashtable的效率大致相同,因?yàn)樗鼈兊膶?shí)現(xiàn)機(jī)制幾乎完全一樣。但HashMap通常比Hashtable要快一點(diǎn),因?yàn)镠ashtable需要額外的線程同步控制

  2. TreeMap通常比HashMap、Hashtable要慢(尤其是在插入、刪除key-value對(duì)時(shí)更慢),因?yàn)門reeMap底層采用紅黑樹來管理key-value對(duì)

  3. 使用TreeMap的一個(gè)好處就是: TreeMap中的key-value對(duì)總是處于有序狀態(tài),無須專門進(jìn)行排序操作

  4. HahMap 是利用hashCode 進(jìn)行查找,而TreeMap 是保持者某種有序狀態(tài)

  5. 所以,插入,刪除,定位操作時(shí),HashMap 是最好的選擇;如果要按照自然排序或者自定義排序,那么就選擇TreeMap

你應(yīng)該知道的JDK知識(shí)

學(xué)習(xí)過程中遇到什么問題或者想獲取學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交流群346942462,我們一起學(xué)Java!

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多