版權信息
原文鏈接:
---
# 前言
無論是從事Javaee開發或者是Android開發,JDK的基礎知識都尤為重要。我們在代碼里經常使用ArrayList、HashMap等,但卻很少思考為什么是使用它,使用的時候需要注意什么。甚至有可能去面試的時候,人家一問HashMap的實現原理,但卻只知道put和get,非常尷尬。
所以為了開發更高質量的程序,寫出更優秀的代碼,還是需要好好研究一下JDK的一些關鍵源碼。本文主要對JDK進行一些重要的的知識的梳理及整理,便于學習及復習。
# 基礎知識
## 基礎數據類型
變量就是申請內存來存儲值。也就是說,當創建變量的時候,需要在內存中申請空間。 內存管理系統根據變量的類型為變量分配存儲空間,分配的空間只能用來儲存該類型數據
| 類型 | 位 | 默認值 |
| --- | --- | --- |
| byte | 8(1字節) | 0 |
| short | 16(2字節) | 0 |
| int | 32(4字節) | 0 |
| long | 64(8字節) | 0L |
| float | 32(4字節) | 0.0f |
| double | 64(8字節) | 0.0d |
| boolean | 1 | false |
| char | 16 位 Unicode 字符 | “” |
## equal hashcode ==的區別
| == | 內存地址比較 |
| --- | --- |
| equal | Object默認內存地址比較,一般需要復寫 |
| hashcode | 主要用于集合的散列表,Object默認為內存地址,一般不用設置,除非作用于散列集合。 |
hashCode 方法的常規協定,該協定聲明相等對象必須具有相等的哈希碼。當equals方法被重寫時,通常有必要重寫 hashCode 方法。但hashCode相等,不一定equals()
## String、StringBuffer與StringBuilder的區別。
Java 平臺提供了兩種類型的字符串:String和StringBuffer / StringBuilder,它們可以儲存和操作字符串。其中String是只讀字符串,也就意味著String引用的字符串內容是不能被改變的。而StringBuffer和StringBulder類表示的字符串對象可以直接進行修改。StringBuilder是JDK1.5引入的,它和StringBuffer的方法完全相同,區別在于它是單線程環境下使用的,因為它的所有方面都沒有被synchronized修飾,因此它的效率也比StringBuffer略高。
# Java的四種引用,強弱軟虛,用到的場景。
JDK1.2之前只有強引用,其他幾種引用都是在JDK1.2之后引入的.
強引用(Strong Reference) 最常用的引用類型,如Object obj = new Object(); 。只要強引用存在則GC時則必定不被回收。
軟引用(Soft Reference) 用于描述還有用但非必須的對象,當堆將發生OOM(Out Of Memory)時則會回收軟引用所指向的內存空間,若回收后依然空間不足才會拋出OOM。一般用于實現內存敏感的高速緩存。 當真正對象被標記finalizable以及的finalize()方法調用之后并且內存已經清理, 那么如果SoftReference object還存在就被加入到它的 ReferenceQueue.只有前面幾步完成后,Soft Reference和Weak Reference的get方法才會返回null
弱引用(Weak Reference) 發生GC時必定回收弱引用指向的內存空間。 和軟引用加入隊列的時機相同
虛引用(Phantom Reference) 又稱為幽靈引用或幻影引用,虛引用既不會影響對象的生命周期,也無法通過虛引用來獲取對象實例,僅用于在發生GC時接收一個系統通知。 當一個對象的finalize方法已經被調用了之后,這個對象的幽靈引用會被加入到隊列中。通過檢查該隊列里面的內容就知道一個對象是不是已經準備要被回收了. 虛引用和軟引用和弱引用都不同,它會在內存沒有清理的時候被加入引用隊列.虛引用的建立必須要傳入引用隊列,其他可以沒有
# Java集合框架

*Java 集合類結構圖*
Collection是List、Set等集合高度抽象出來的接口,它包含了這些集合的基本操作,它主要又分為兩大部分:List和Set。
List接口通常表示一個列表(數組、隊列、鏈表、棧等),其中的元素可以重復,常用實現類為ArrayList和LinkedList,另外還有不常用的Vector。另外,LinkedList還是實現了Queue接口,因此也可以作為隊列使用。
Set接口通常表示一個集合,其中的元素不允許重復(通過hashcode和equals函數保證),常用實現類有HashSet和TreeSet,HashSet是通過Map中的HashMap實現的,而TreeSet是通過Map中的TreeMap實現的。另外,TreeSet還實現了SortedSet接口,因此是有序的集合(集合中的元素要實現Comparable接口,并覆寫Compartor函數才行)。 我們看到,抽象類AbstractCollection、AbstractList和AbstractSet分別實現了Collection、List和Set接口,這就是在Java集合框架中用的很多的適配器設計模式,用這些抽象類去實現接口,在抽象類中實現接口中的若干或全部方法,這樣下面的一些類只需直接繼承該抽象類,并實現自己需要的方法即可,而不用實現接口中的全部抽象方法。
Map是一個映射接口,其中的每個元素都是一個key-value鍵值對,同樣抽象類AbstractMap通過適配器模式實現了Map接口中的大部分函數,TreeMap、HashMap、WeakHashMap等實現類都通過繼承AbstractMap來實現,另外,不常用的HashTable直接實現了Map接口,它和Vector都是JDK1.0就引入的集合類。
Iterator是遍歷集合的迭代器(不能遍歷Map,只用來遍歷Collection),Collection的實現類都實現了iterator()函數,它返回一個Iterator對象,用來遍歷集合,ListIterator則專門用來遍歷List。而Enumeration則是JDK1.0時引入的,作用與Iterator相同,但它的功能比Iterator要少,它只能再Hashtable、Vector和Stack中使用。
Arrays和Collections是用來操作數組、集合的兩個工具類,例如在ArrayList和Vector中大量調用了Arrays.Copyof()方法,而Collections中有很多靜態方法可以返回各集合類的synchronized版本,即線程安全的版本,當然了,如果要用線程安全的結合類,首選Concurrent并發包下的對應的集合類。
## Collection List Set Map 區別
| 接口 | 是否有序 | 允許元素重復 |
| --- | --- | --- |
| collection | 否 | 是 |
| List | 是 | 是 |
| AbstractSet | 否 | 否 |
| HashSet | 否 | 否 |
| TreeSet | 是(用二叉樹排序) | 否 |
| AbstractMap | 否 | 使用 key-value 來映射和存儲數據, Key 必須惟一, value 可以重復 |
| HashMap | 否 | 使用 key-value 來映射和存儲數據, Key 必須惟一, value 可以重復 |
| TreeMap | 是(用二叉樹排序) | 使用 key-value 來映射和存儲數據, Key 必須惟一, value |
## 常用集合分析
| 集合 | 主要算法 | 源碼分析 |
| --- | --- | --- |
| ArrayList | 基于數組的List,封裝了動態增長的Object[] 數組 | [huangjunbin.com/2016/11/14/…](https://link.juejin.im/?target=http%3A%2F%2Fhuangjunbin.com%2F2016%2F11%2F14%2F%25E7%25BA%25BF%25E6%2580%25A7%25E5%25AD%2598%25E5%2582%25A8%25E7%25BB%2593%25E6%259E%2584-ArrayList%25E3%2580%2581Vector%2F) |
| Stack | 是Vector 的子類,棧 的結構(后進先出) | [huangjunbin.com/2016/11/14/…](https://link.juejin.im/?target=http%3A%2F%2Fhuangjunbin.com%2F2016%2F11%2F14%2F%25E7%25BA%25BF%25E6%2580%25A7%25E5%25AD%2598%25E5%2582%25A8%25E7%25BB%2593%25E6%259E%2584-Stack%2F) |
| LinkedList | 實現List,Deque;實現List,可以進行隊列操作,可以通過索引來隨機訪問集合元素;實現Deque,也可當作雙端隊列,也可當作棧來使用 | [huangjunbin.com/2016/11/14/…](https://link.juejin.im/?target=http%3A%2F%2Fhuangjunbin.com%2F2016%2F11%2F14%2F%25E7%25BA%25BF%25E6%2580%25A7%25E5%25AD%2598%25E5%2582%25A8%25E7%25BB%2593%25E6%259E%2584-LinkedList%2F) |
| HashMap | 基于哈希表的 Map 接口的實現, 使用順序存儲及鏈式存儲的結構 | [huangjunbin.com/2016/11/24/…](https://link.juejin.im/?target=http%3A%2F%2Fhuangjunbin.com%2F2016%2F11%2F24%2F%25E9%25A1%25BA%25E5%25BA%258F%25E5%25AD%2598%25E5%2582%25A8%25E4%25B8%258E%25E9%2593%25BE%25E5%25BC%258F%25E5%25AD%2598%25E5%2582%25A8%25E7%259A%2584%25E9%259B%2586%25E5%2590%2588-HashMap%25E3%2580%2581HashTable%2F) |
| LinkedHashMap | LinkedHashMap是HashMap的子類,與HashMap有著同樣的存儲結構,但它加入了一個雙向鏈表的頭結點,將所有put到LinkedHashmap的節點一一串成了一個雙向循環鏈表,因此它保留了節點插入的順序,可以使節點的輸出順序與輸入順序相同 | [github.com/francistao/…](https://link.juejin.im/?target=https%3A%2F%2Fgithub.com%2Ffrancistao%2FLearningNotes%2Fblob%2Fmaster%2FPart2%2FJavaSE%2FLinkedHashMap%25E6%25BA%2590%25E7%25A0%2581%25E5%2589%2596%25E6%259E%2590.md) |
| TreeMap | TreeMap的實現是紅黑樹算法的實現,支持排序 | [blog.csdn.net/chenssy/art…](https://link.juejin.im/?target=http%3A%2F%2Fblog.csdn.net%2Fchenssy%2Farticle%2Fdetails%2F26668941) |
## 并發
Lists
* ArrayList——基于泛型數組
* LinkedList——不推薦使用
* Vector——已廢棄(deprecated)
CopyOnWriteArrayList——幾乎不更新,常用來遍歷
Queues / deques
* ArrayDeque——基于泛型數組
* Stack——已廢棄(deprecated)
* PriorityQueue——讀取操作的內容已排序
* ArrayBlockingQueue——帶邊界的阻塞式隊列
* ConcurrentLinkedDeque / ConcurrentLinkedQueue——無邊界的鏈表隊列(CAS)
* DelayQueue——元素帶有延遲的隊列
* LinkedBlockingDeque / LinkedBlockingQueue——鏈表隊列(帶鎖),可設定是否帶邊界
* LinkedTransferQueue——可將元素`transfer`進行w/o存儲
* PriorityBlockingQueue——并發PriorityQueue
* SynchronousQueue——使用Queue接口進行Exchanger
Maps
* HashMap——通用Map
* EnumMap——鍵使用enum
* Hashtable——已廢棄(deprecated)
* IdentityHashMap——鍵使用==進行比較
* LinkedHashMap——保持插入順序
* TreeMap——鍵已排序
* WeakHashMap——適用于緩存(cache)
* ConcurrentHashMap——通用并發Map
* ConcurrentSkipListMap——已排序的并發Map
Sets
* HashSet——通用set
* EnumSet——enum Set
* BitSet——比特或密集的整數Set
* LinkedHashSet——保持插入順序
* TreeSet——排序Set
* ConcurrentSkipListSet——排序并發Set
* CopyOnWriteArraySet——幾乎不更新,通常只做遍歷
## 總結
Set的選擇
1. HashSet的性能總是比TreeSet好(特別是最常用的添加、查詢元素等操作),因為TreeSet需要額外的紅黑樹算法來維護集合元素的次序。只有當需要一個保持排序的Set時,才應該使用TreeSet,否則都應該使用HashSet
2. 對于普通的插入、刪除操作,LinkedHashSet比HashSet要略慢一點,這是由維護鏈表所帶來的開銷造成的。不過,因為有了鏈表的存在,遍歷LinkedHashSet會更快
3. EnumSet是所有Set實現類中性能最好的,但它只能保存同一個枚舉類的枚舉值作為集合元素
4. HashSet、TreeSet、EnumSet都是"線程不安全"的,通常可以通過Collections工具類的synchronizedSortedSet方法來"包裝"該Set集合。
SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));
List 選擇
1. java提供的List就是一個"線性表接口",ArrayList(基于數組的線性表)、LinkedList(基于鏈的線性表)是線性表的兩種典型實現
2. Queue代表了隊列,Deque代表了雙端隊列(既可以作為隊列使用、也可以作為棧使用)
3. 因為數組以一塊連續內存來保存所有的數組元素,所以數組在隨機訪問時性能最好。所以的內部以數組作為底層實現的集合在隨機訪問時性能最好。
4. 內部以鏈表作為底層實現的集合在執行插入、刪除操作時有很好的性能
5. 進行迭代操作時,以鏈表作為底層實現的集合比以數組作為底層實現的集合性能好
6. 當要大量的插入,刪除,應當選用LinkedList;當需要快速隨機訪問則選用ArrayList;
Map 的選擇
1. HashMap和Hashtable的效率大致相同,因為它們的實現機制幾乎完全一樣。但HashMap通常比Hashtable要快一點,因為Hashtable需要額外的線程同步控制
2. TreeMap通常比HashMap、Hashtable要慢(尤其是在插入、刪除key-value對時更慢),因為TreeMap底層采用紅黑樹來管理key-value對
3. 使用TreeMap的一個好處就是: TreeMap中的key-value對總是處于有序狀態,無須專門進行排序操作
4. HahMap 是利用hashCode 進行查找,而TreeMap 是保持者某種有序狀態
5. 所以,插入,刪除,定位操作時,HashMap 是最好的選擇;如果要按照自然排序或者自定義排序,那么就選擇TreeMap
# 參考
[Java 學習之集合類(Collections)](https://link.juejin.im/?target=http%3A%2F%2Fwww.imooc.com%2Farticle%2F1080)
[Java集合總覽](https://link.juejin.im/?target=http%3A%2F%2Fwww.importnew.com%2F13801.html)
[JavaSE(Java基礎)](https://link.juejin.im/?target=https%3A%2F%2Fgithub.com%2Ffrancistao%2FLearningNotes%2Ftree%2Fmaster%2FPart2%2FJavaSE)
- 0-發現
- AndroidInterview-Q-A
- Android能讓你少走彎路的干貨整理
- LearningNotes
- temp
- temp11
- 部分地址
- 0-待辦任務
- 待補充列表
- 0-未分類
- AndroidView事件分發與滑動沖突處理
- Spannable
- 事件分發機制詳解
- 1-Java
- 1-Java-01基礎
- 未歸檔
- 你應該知道的JDK知識
- 集合框架
- 1-Java-04合集
- Java之旅0
- Java之旅
- JAVA之旅01
- JAVA之旅02
- JAVA之旅03
- JAVA之旅04
- JAVA之旅05
- JAVA之旅06
- JAVA之旅07
- JAVA之旅08
- JAVA之旅09
- java之旅1
- JAVA之旅10
- JAVA之旅11
- JAVA之旅12
- JAVA之旅13
- JAVA之旅14
- JAVA之旅15
- JAVA之旅16
- JAVA之旅17
- JAVA之旅18
- JAVA之旅19
- java之旅2
- JAVA之旅20
- JAVA之旅21
- JAVA之旅22
- JAVA之旅23
- JAVA之旅24
- JAVA之旅25
- JAVA之旅26
- JAVA之旅27
- JAVA之旅28
- JAVA之旅29
- java之旅3
- JAVA之旅30
- JAVA之旅31
- JAVA之旅32
- JAVA之旅33
- JAVA之旅34
- JAVA之旅35
- 1-Java-05辨析
- HashMapArrayMap
- Java8新特性
- Java8接口默認方法
- 圖解HashMap(1)
- 圖解HashMap(2)
- 2-Android
- 2-Android-1-基礎
- View繪制流程
- 事件分發
- AndroidView的事件分發機制和滑動沖突解決
- 自定義View基礎
- 1-安卓自定義View基礎-坐標系
- 2-安卓自定義View基礎-角度弧度
- 3-安卓自定義View基礎-顏色
- 自定義View進階
- 1-安卓自定義View進階-分類和流程
- 10-安卓自定義View進階-Matrix詳解
- 11-安卓自定義View進階-MatrixCamera
- 12-安卓自定義View進階-事件分發機制原理
- 13-安卓自定義View進階-事件分發機制詳解
- 14-安卓自定義View進階-MotionEvent詳解
- 15-安卓自定義View進階-特殊形狀控件事件處理方案
- 16-安卓自定義View進階-多點觸控詳解
- 17-安卓自定義View進階-手勢檢測GestureDetector
- 2-安卓自定義View進階-繪制基本圖形
- 3-安卓自定義View進階-畫布操作
- 4-安卓自定義View進階-圖片文字
- 5-安卓自定義View進階-Path基本操作
- 6-安卓自定義View進階-貝塞爾曲線
- 7-安卓自定義View進階-Path完結篇偽
- 8-安卓自定義View進階-Path玩出花樣PathMeasure
- 9-安卓自定義View進階-Matrix原理
- 通用類介紹
- Application
- 2-Android-2-使用
- 2-Android-02控件
- ViewGroup
- ConstraintLayout
- CoordinatorLayout
- 2-Android-03三方使用
- Dagger2
- Dagger2圖文完全教程
- Dagger2最清晰的使用教程
- Dagger2讓你愛不釋手-終結篇
- Dagger2讓你愛不釋手-重點概念講解、融合篇
- dagger2讓你愛不釋手:基礎依賴注入框架篇
- 閱讀筆記
- Glide
- Google推薦的圖片加載庫Glide:最新版使用指南(含新特性)
- rxjava
- 這可能是最好的RxJava2.x入門教程完結版
- 這可能是最好的RxJava2.x入門教程(一)
- 這可能是最好的RxJava2.x入門教程(三)
- 這可能是最好的RxJava2.x入門教程(二)
- 這可能是最好的RxJava2.x入門教程(五)
- 這可能是最好的RxJava2.x入門教程(四)
- 2-Android-3-優化
- 優化概況
- 各種優化
- Android端秒開優化
- apk大小優化
- 內存分析
- 混淆
- 2-Android-4-工具
- adb命令
- 一鍵分析Android的BugReport
- 版本控制
- git
- git章節簡述
- 2-Android-5-源碼
- HandlerThread 源碼分析
- IntentService的使用和源碼分析
- 2-Android-9-辨析
- LRU算法
- 什么是Bitmap
- 常見圖片壓縮方式
- 3-Kotlin
- Kotlin使用筆記1-草稿
- Kotlin使用筆記2
- kotlin特性草稿
- Kotlin草稿-Delegation
- Kotlin草稿-Field
- Kotlin草稿-object
- 4-JavaScript
- 5-Python
- 6-Other
- Git
- Gradle
- Android中ProGuard配置和總結
- gradle使用筆記
- Nexus私服搭建
- 編譯提速最佳實踐
- 7-設計模式與架構
- 組件化
- 組件化探索(OKR)
- 1-參考列表
- 2-1-組件化概述
- 2-2-gradle配置
- 2-3-代碼編寫
- 2-4-常見問題
- 2-9-值得一讀
- 8-數據結構與算法
- 0臨時文件
- 漢諾塔
- 8-數據-1數據結構
- HashMap
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比較
- 遲到一年HashMap解讀
- 8-數據-2算法
- 1個就夠了
- Java常用排序算法(必須掌握的8大排序算法)
- 常用排序算法總結(性能+代碼)
- 必須知道的八大種排序算法(java實現)
- 9-職業
- 閱讀
- 書單
- 面試
- 面試-01-java
- Java面試題全集駱昊(上)
- Java面試題全集駱昊(下)
- Java面試題全集駱昊(中)
- 面試-02-android
- 40道Android面試題
- 面試-03-開源源碼
- Android圖片加載框架最全解析(二),從源碼的角度理解Glide的執行流程
- 面試-07-設計模式
- 面試-08-算法
- 面試-09-其他
- SUMMARY
- 版權說明
- temp111