Java基礎-----與Java集合相關的數據結構&Java集合特點、底層實現、是否線程安全&集合使用選取原則&集合的常見方法及遍歷方式
Java基礎-----與Java集合相關的數據結構&Java集合特點、底層實現、是否線程安全&集合使用選取原則&集合的常見方法及遍歷方式
與Java集合相關的數據結構
棧
隊列
數組
鏈表
紅黑樹
直觀圖示
詳解紅黑樹
紅黑樹介紹
紅黑樹又稱R-B Tree,全稱是Red-Black Tree,它是一種特殊的二叉查找樹,紅黑樹的每個節點上都有存儲位表示節點的顏色,可以是紅或黑。
紅黑樹具有以下五個特性:
1)每個節點或者是黑色,或者是紅色
2)根節點是黑色
3)每個葉子結點(NIL,這裏的葉子結點不是傳統的葉子結點,是指爲空的葉子結點)是黑色。
4)如果一個結點是紅色的,則它的子結點必須是黑色的
5)從一個結點到該結點的子孫結點的所有路徑上包含相同數目的黑結點。
根據特性5,可以確保沒有一條路徑會比其他路徑長處兩倍,因而,紅黑樹是相對接近平衡的二叉樹。因爲操作比如插入、刪除和查找某個值的最壞情況時間都要求與樹的高度成比例,這個在高度上的理論上限允許紅黑樹在最壞情況下都是高效的,而不同於普通的二叉查找樹。
爲什麼說紅黑樹有一條路徑會比其他路徑長處兩倍呢,注意到性質4導致了路徑不能有兩個毗連的紅色節點就足夠了。最短的可能路徑都是黑色節點,最長的可能路徑有交替的紅色和黑色節點。因爲根據性質5所有最長的路徑都有相同數目的黑色節點,這就表明了沒有路徑能多於任何其他路徑的兩倍長。
紅黑樹的應用
紅黑樹的應用比較廣泛,主要是用它來存儲有序的數據,它的時間複雜度是O(lgn)O(lgn),效率非常之高。
例如,Java集合中的TreeSet和TreeMap,HashSet(數組+紅黑樹:當哈希衝突的元素數大於8時)
C++的STL中的Set、Map,以及Linux虛擬內存的管理,都是通過紅黑樹去實現的。
紅黑樹的時間複雜度爲: O(lgn)
紅黑樹基本操作
紅黑樹的基本操作是添加、刪除。在對紅黑樹進行添加或刪除之後,都會用到旋轉方法。爲什麼呢?道理很簡單,添加或者刪除紅黑樹中的結點之後,紅黑樹就發生了變化,可能不滿足紅黑樹的5條性質,也就不再是一棵紅黑樹了,而是一棵普通的樹。而通過旋轉,可以使這棵樹重新成爲紅黑樹。簡單點說,旋轉的目的是讓樹保持紅黑樹的特性。
Java集合特點、底層實現、是否線程安全
List
List(有序,可重複)
ArrayList
底層數據結構是數組,查詢快,增刪慢
線程不安全,效率高
LinkedList
底層數據結構是鏈表,查詢慢,增刪快
線程不安全,效率高
Vector
底層數據結構是數組,查詢快,增刪慢
線程安全,效率低
Set
Set(無序,唯一)
HashSet
底層數據結構是哈希表。
哈希表依賴兩個方法:hashCode()和equals()
執行順序:
首先判斷hashCode()值是否相同
是:繼續執行equals(),看其返回值
是true:說明元素重複,不添加
是false:就直接添加到集合
否:就直接添加到集合
最終:
自動生成hashCode()和equals()即可
LinkedHashSet
底層數據結構由鏈表和哈希表組成。
由鏈表保證元素有序。
由哈希表保證元素唯一。
TreeSet
底層數據結構是紅黑樹。(是一種自平衡的二叉樹)
如何保證元素唯一性呢?
根據比較的返回值是否是0來決定
如何保證元素的排序呢?
兩種方式
自然排序(元素具備比較性)
讓元素所屬的類實現Comparable接口
比較器排序(集合具備比較性)
讓集合接收一個Comparator的實現類對象
Map
Map(雙列集合)
A:Map集合的數據結構僅僅針對鍵有效,與值無關。
B:存儲的是鍵值對形式的元素,鍵唯一,值可重複。
HashMap
底層數據結構是哈希表。線程不安全,效率高
哈希表依賴兩個方法:hashCode()和equals()
執行順序:
首先判斷hashCode()值是否相同
是:繼續執行equals(),看其返回值
是true:說明元素重複,不添加
是false:就直接添加到集合
否:就直接添加到集合
最終:
自動生成hashCode()和equals()即可
LinkedHashMap
底層數據結構由鏈表和哈希表組成。
由鏈表保證元素有序。
由哈希表保證元素唯一。
Hashtable
底層數據結構是哈希表。線程安全,效率低
哈希表依賴兩個方法:hashCode()和equals()
執行順序:
首先判斷hashCode()值是否相同
是:繼續執行equals(),看其返回值
是true:說明元素重複,不添加
是false:就直接添加到集合
否:就直接添加到集合
最終:
自動生成hashCode()和equals()即可
TreeMap
底層數據結構是紅黑樹。(是一種自平衡的二叉樹)
如何保證元素唯一性呢?
根據比較的返回值是否是0來決定
如何保證元素的排序呢?
兩種方式
自然排序(元素具備比較性)
讓元素所屬的類實現Comparable接口
比較器排序(集合具備比較性)
讓集合接收一個Comparator的實現類對象
集合使用選取原則
是否是鍵值對象形式:
是:Map
鍵是否需要排序:
是:TreeMap
否:HashMap
不知道,就使用HashMap。
否:Collection
元素是否唯一:
是:Set
元素是否需要排序:
是:TreeSet
否:HashSet
不知道,就使用HashSet
否:List
要安全嗎:
是:Vector
否:ArrayList或者LinkedList
增刪多:LinkedList
查詢多:ArrayList
不知道,就使用ArrayList
不知道,就使用ArrayList
集合的常見方法及遍歷方式
Collection:
add()
remove()
contains()
iterator()
size()
遍歷:
增強for
迭代器
|--List
get()
遍歷:
普通for
|--Set
Map:
put()
remove()
containskey(),containsValue()
keySet()
get()
value()
entrySet()
size()
遍歷:
根據鍵找值
根據鍵值對對象分別找鍵和值
總結
一般Linked開頭的都是鏈表。Array開頭的都是數組。Tree開頭的就是二叉樹。Hash開頭的就是散列表。
經常增添、刪除,且還需要檢索時爲插入順序用Linked 和 linkedhash
經常增添、刪除用hash
如果要自動排序 且 去重 用 Tree
經常需要遍歷查數據,用Array,遍歷ArrayList用for循環效率比迭代器高。