單列集合:
頂層接口是collection集合,下分接口為List集合和Set集合,
List集合有序可重復(fù)有索引(有序指的是存和取的順序一樣,數(shù)據(jù)可以重復(fù),可以通過索引取出任意一條數(shù)據(jù))List下分實現(xiàn)類為ArrayList、LinkedList、Vector(淘汰),
Set集合無序不可重復(fù)無索引(存和取的順序可能不一樣,數(shù)據(jù)不重復(fù),不能通過索引取出指定一條數(shù)據(jù)),Set下分實現(xiàn)類為HashSet、TreeSet,HashSet下分實現(xiàn)類有LinkedHashSet
單列集合-數(shù)據(jù)結(jié)構(gòu)(棧、隊列、數(shù)組、鏈表)
棧 先進先出 后進后出
隊列 先進后出 后進先出
數(shù)組 查詢快 增刪慢 (內(nèi)存連續(xù) 通過數(shù)組地址值+元素索引值查詢)
鏈表-單向、雙向 查詢慢 增刪快 (內(nèi)存不連續(xù) 通過頭節(jié)點往后遍歷查詢)
二叉樹:每一個節(jié)點的子節(jié)點數(shù)<=2
二叉查找樹 :添加時比當(dāng)前節(jié)點小的數(shù)去左邊,比當(dāng)前節(jié)點大的數(shù)去右邊,不存相同的數(shù)
平衡二叉樹 :任何一個節(jié)點的左右子樹高度差不超過1
左旋:從添加的節(jié)點開始向上找到第一個不滿足平衡二叉樹規(guī)則的節(jié)點作為支點,
支點的右孩子代替支點的位置,右孩子的左子樹作為支點的右子樹,支點變成右孩子的左子樹
右旋:從添加的節(jié)點開始向上找到第一個不滿足平衡二叉樹規(guī)則的節(jié)點作為支點,
支點的左孩子代替支點的位置,左孩子的右子樹代替支點的左子樹,支點作為左孩子的右子樹
紅黑樹(特殊的二叉查找樹):1.每一個節(jié)點不是黑色就是紅色 2.根節(jié)點必須是黑色 3.葉子結(jié)點是黑色的 4.不能存在兩個連續(xù)的紅節(jié)點 5.每一個節(jié)點下的簡單路徑中黑節(jié)點數(shù)相同
添加操作(默認(rèn)添加紅節(jié)點):
情況1.添加的是根節(jié)點 需要變黑色
情況2.添加的不是根節(jié)點,父節(jié)點為黑色 不需要操作
情況3.添加的不是根節(jié)點,父節(jié)點為紅色,叔叔節(jié)點為紅色
將父節(jié)點和叔叔節(jié)點都變成黑色,將祖父節(jié)點變成紅色(如果祖父節(jié)點不是根節(jié)點),再判斷祖父節(jié)點是否合理
情況4.添加的不是根節(jié)點,父節(jié)點為紅色,叔叔節(jié)點為黑色,當(dāng)前節(jié)點為左孩子
將父節(jié)點變成黑色,叔叔節(jié)點變成紅色,以祖父節(jié)點為支點進行右旋
情況5.添加的不是根節(jié)點,父節(jié)點為紅色,叔叔節(jié)點為黑色,當(dāng)前節(jié)點為右孩子
將父節(jié)點作為支點進行左旋,再重新判斷父節(jié)點是否合理
哈希表:jdk8之前是數(shù)組+鏈表;jdk8之后是數(shù)組+鏈表+紅黑樹
哈希值:對象的整數(shù)表現(xiàn)形式
沒有重寫hashCode方法(默認(rèn)使用了地址值參與計算),不同對象計算出的哈希值不同
重寫了hashCode方法(使用屬性值參與計算),不用對象只要屬性值相同,計算出的哈希值就相同
存在不同屬性值或者不同地址值計算出的哈希值相同的情況,哈希碰撞
添加操作(數(shù)組默認(rèn)長度16,擴容因子0.75):
通過哈希值&(數(shù)組長度-1)計算出元素的位置,判斷該位置是否為null,為null直接存,
不為bull就判斷是否相同,不相同放在原元素后面變成鏈表(jdk8之前是替代原元素位置,原元素向后移變成鏈表),
當(dāng)鏈表長度>8并且數(shù)組長度>=64時,鏈表轉(zhuǎn)化為紅黑樹
集合中使用的是自定義對象時,要重寫hashCode,equals方法,使其從判斷地址值變成判斷屬性值是否相同。
HashSet: 無序 不重復(fù) 無索引
底層哈希表:jdk8之前是數(shù)組+鏈表;jdk8之后是數(shù)組+鏈表+紅黑樹
添加操作(數(shù)組默認(rèn)長度16,擴容因子0.75):
通過哈希值&(數(shù)組長度-1)計算出元素的位置,判斷該位置是否為null,為null直接存,
不為null就判斷是否相同,不相同則放在原元素后面變成鏈表(jdk8之前是替代原元素位置,原元素向后移變成鏈表),
當(dāng)鏈表長度>8并且數(shù)組長度>=64時,鏈表轉(zhuǎn)化為紅黑樹
為什么存取順序不一樣:因為HashSet讀取是從數(shù)組頭依次遍歷鏈表元素
為什么沒有索引:存在鏈表結(jié)構(gòu),無法用數(shù)組的索引規(guī)定鏈表中具體元素的索引
去重機制:hashCode方法確定元素位置,equals方法比較元素屬性值,因此當(dāng)集合中使用的是自定義對象時,要重寫hashCode,equals方法,使其從判斷地址值變成判斷屬性值是否相同
LinkedHashSet: 有序 不重復(fù) 無索引
底層哈希表(數(shù)組+鏈表+紅黑樹)+雙向鏈表
添加操作:同HashSet
為什么存取順序一樣:因為添加時額外生成一條雙向鏈表,記錄節(jié)點之間的前后順序,讀取時直接讀這個雙向鏈表
TreeSet: 可排序(默認(rèn)從小到大) 不重復(fù) 無索引
底層紅黑樹
排序規(guī)則:
一.默認(rèn)排序:(選,若無法滿足需求則使用比較器排序)
1.整數(shù)類型、浮點數(shù)類型:直接比較
2.字符類型:按ASCLL碼表中的順序
3.自定義類型:需要自定義類實現(xiàn)Comparable接口,泛型為該自定義類型,并重寫其中的compareTo方法,規(guī)定排序規(guī)則。不然會報錯
@Override
public int compareTo(Student o){
//按照年齡升序
return this.getAge()-o.getAge();
}
二.比較器排序:創(chuàng)建集合時,自定義Comparator比較器對象,指定比較規(guī)則。
collection接口中包含的方法:
add() 向集合中添加一個元素(返回布爾類型)
clear() 清空集合中所有元素(返回void)
remove() 刪除集合中的某一個元素(返回布爾類型)
contains() 判斷集合中是否包含某一元素(返回值是布爾類型)
isEmpty() 判斷集合是否為空(返回值是布爾類型,底層是判斷元素個數(shù)是否為0)
size() 返回集合中元素的個數(shù)|集合的長度(返回值int類型)
ArrayList底層邏輯:數(shù)組結(jié)構(gòu)
add過程:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;//將元素e存到數(shù)組size的位置,size+1
return true;
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//若當(dāng)前數(shù)組為空
return Math.max(DEFAULT_CAPACITY, minCapacity);返回默認(rèn)數(shù)組容量與最小容量的大值賦值給minCapacity,
}
return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//操作次數(shù)加1
// overflow-conscious code
if (minCapacity - elementData.length >0)//如果此時所需要的最小容量比數(shù)組長度大,數(shù)組需要擴容
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//將數(shù)組長度賦值給老容量值
int newCapacity = oldCapacity + (oldCapacity >>1);//將老容量+老容量/2作為新容量值
if (newCapacity - minCapacity< 0)//如果新的容量值太小,不滿足所需要的最小容量,就按照所需最小容量擴容
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE >0)//如果新容量值太大,超出了規(guī)定的數(shù)組大值,
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//將原來的數(shù)組數(shù)據(jù)轉(zhuǎn)移到擴容完成的數(shù)組中
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity< 0) // overflow
throw new OutOfMemoryError();
return (minCapacity >MAX_ARRAY_SIZE) ?//如果所需要的最小容量值比規(guī)定的大值大,新容量值就用更大的整數(shù)大值
Integer.MAX_VALUE ://反之則用數(shù)據(jù)大值
MAX_ARRAY_SIZE;
}
LinkedList底層邏輯:雙向鏈表結(jié)構(gòu)
add過程:
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Nodel = last;//將鏈表的最后一個結(jié)點last賦值給結(jié)點l
//創(chuàng)建一個新結(jié)點newNode,以l的地址值為prev值,以元素e作為element值,以null作為next值
final NodenewNode = new Node<>(l, e, null);
last = newNode;//將新結(jié)點賦值給last,作為鏈表的尾結(jié)點
if (l == null)//如果鏈表為空,將新結(jié)點賦值給first結(jié)點,作為頭結(jié)點
first = newNode;
else//反之將結(jié)點l的指針指向新結(jié)點(next值改為newNode結(jié)點的地址值)
l.next = newNode;
size++;//鏈表長度+1
modCount++;//操作次數(shù)+1
}
private static class Node{
E item;//該結(jié)點的元素值
Nodenext;//該結(jié)點后一個結(jié)點的地址值
Nodeprev;//該結(jié)點前一個結(jié)點的地址值
Node(Nodeprev, E element, Nodenext) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
iterator底層邏輯:
public Iteratoriterator() {
return new Itr();
}
private class Itr implements Iterator{
int cursor; // 指針
int lastRet = -1; // 指針的上一個位置
int expectedModCount = modCount;//將集合的修改次數(shù)同步給迭代器
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();//檢查集合操作次數(shù)
int i = cursor;
if (i >= size)//如果指針?biāo)肝恢贸黾洗笮?,拋出沒有元素異常
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;//將集合重新賦值
if (i >= elementData.length)//如果此時指針超出集合長度,拋出并發(fā)修改異常
throw new ConcurrentModificationException();
cursor = i + 1;//指針后移
return (E) elementData[lastRet = i];//把指針的上一個位置賦值給lastRet并返回該位置的元素值
}
final void checkForComodification() {
if (modCount != expectedModCount)//如果此時集合修改次數(shù)與迭代器中修改次數(shù)不相等,拋出并發(fā)修改異常
throw new ConcurrentModificationException();
}
雙列集合:
Map為頂層接口,下分實現(xiàn)類為HashMap、TreeMap,HashMap下分實現(xiàn)類為LinkedHashMap
Map集合特點:
每次存儲都需要存一對數(shù)據(jù),分為鍵和值;
一個集合中,鍵不可以重復(fù),值可以重復(fù);
鍵和值是一一對應(yīng)的關(guān)系;
鍵和值合稱為鍵值對,java中也叫做entry對象;
Map接口中的方法:
put() 集合中添加或者覆蓋元素 (返回覆蓋原鍵對應(yīng)的值,若不存在相同的鍵則返回null)
remove() 刪除該集合中的某個鍵值對 (返回刪除鍵對應(yīng)的值,類型由該值類型決定)
clear() 清空集合中的鍵值對(返回void)
containsKey() 判斷集合中是否存在該鍵 (返回值為布爾類型,有就是true,沒有就是false)
containsValue() 判斷集合中是否存在該值 (返回值為布爾類型,有就是true,沒有就是false)
isEmpty() 判斷集合是否為空(返回類型為布爾類型,空為true,不空為false)
size() 返回集合中元素的個數(shù)|集合的長度 (返回類型為int類型)
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
文章題目:java集合(fromzero)-創(chuàng)新互聯(lián)
分享鏈接:http://jinyejixie.com/article30/gpipo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、品牌網(wǎng)站制作、云服務(wù)器、網(wǎng)站導(dǎo)航、面包屑導(dǎo)航、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容