

上一節你看過了LinkedList的add方法原始碼,是不是已經打開了思路呢?其實核心原理就是輔助指標+Node雙向鏈表資料結構而已,
相信經過前面的學習,你應該熱身完畢了,之后的學習可以讓我們可以加快速度了,
GO!GO!
這一節你還需要深入LinkedList的其他方法探索下它們的底層原理是什么,
學完這一節,你可以自己寫出一個LinkedList,甚至可以舉一反三寫出單向鏈表的List,逆轉一個單向鏈表等等,你也可以攻克很多鏈表的演算法題,面試問到ArrayList和LinkedList的時候,相信你也會信手拈來,
讓我們一起開始吧!
另一個add(int index,E e)方法
另一個add(int index,E e)方法
有了之前的經驗,相信現在你不需要我在一步一步帶著你看原始碼原理了,我直接將核心原始碼+配圖的方式給大家講解下原理,你更多的是要根據我的這個思路自己把原始碼閱讀一下,自己畫圖講給別人聽聽才是最好的學習方法,
首先來看下另一個add方法,在某個位置增加一個元素,核心原始碼原理圖如下所示:

從add方法原始碼脈絡可以看到,當呼叫的add方法時,會根據要插入的位置index判斷,是否向尾節點添加元素,如果是和上一節講的普通add(E e)方法一樣,呼叫了linkLast方法而已,主要不同的是當不是向尾節點添加元素時,呼叫了linkBefore方法,
而 linkBefore核心是通過node(int index)定位元素的,如下圖所示:

先看原始碼的脈絡,核心是一個if,兩個for回圈,再看下細節,if條件是什么意思?如圖中所示,就是進行了右移1,和除以2相似,類似于二分法的思想,接著for回圈,通過x.next或x.prev開始從前或者從后向前尋找元素,
這個思路是不是,還是個不錯的亮點,很多時候演算法都會有二分法,或者分而治之的思想,
當通過node方法確認了index位置的元素后,就開始執行linkBefore方法了,如下圖所示:

上面原始碼脈絡,主要分三步,你可以跟著如下思路看:
1、將之前node定位的元素記為succ傳入,通過一個輔助指標pred指向定位元素的前一個節點,
2、之后創建一個newNode,它的prev指標指向pred所在位置,尾指標指向succ,也就是定位的元素,
3、最后修改定位元素的prev指標,指向新元素,修改pred位置的元素尾指標指向新元素,
最后就會形成上圖的結果了,其實你可以發現,和linkLast很像,linkLast是通過輔助指標l指向last,來幫助在結尾添加節點的,而linkBefore是通過,先定位元素后,用定位元素的prev前一個節點作為輔助,插入元素的,你只要記住這個思路,一定能自己手寫出來兩種add方法的,
remove系列方法
remove系列方法
LinkedList的remove方法,大多都很相似,都是一些指標變換,你分析的最好方法還是畫圖,
相信到這里,你已經掌味訓本分析原始碼的方式和方法了,這里就不再一步一步帶大家看原始碼了,直接給大家講解下原始碼的原理圖可以了,
首先是removeLast方法的原始碼原理圖,如下所示:

原始碼的核心的脈絡就是使用一個l指標,記錄了尾節點的位置,之后通過l.prev找到之前的元素,記錄下為prev,和最后一個元素斷開l.next=null,讓last指標指向新的尾節點prev即可,
再看看removeFirst方法的原理圖:

你其實可以看到和之前removeLast很像,只不過是使用f指標,記錄了頭節點位置,之后next記錄下f.next,斷開和原頭節點的連接next.prev=null,最后再讓first指標指向新的頭結點,
其實你只要記住這個思路就可以,雙向鏈表使用一個輔助指標記錄prev或next的位置+頭/尾指標,就可以非常簡單的實作從頭節點或者尾節點洗掉元素,手寫應該也不是什么難事,
最后你來看下remove(index)方法的原始碼原理圖:

可以看到,remove(index)方法,通過node方法定位元素,之后使用了兩個輔助指標,prev和next分別記錄了所定位元素的前后節點,
定位元素的原始碼原理上一節已經講過了,就是二分法+for回圈遍歷查找而已,通過prev和next兩個指標,就可以分別斷開定位元素x的前后指標,并且next和prev重新相接,就實作了從某個位置洗掉元素了,
核心原理,就是定位+前后輔助指標來實作的,你要記住這點思路就可以自己嘗試手寫remove方法了,
到這里LinkedList的核心方法就帶大家看完了,它還有一些高級方法,addAll、toArray等等,你可以自己簡單的看下,現在對你其實沒什么難度的,大家看這些方法找到核心原理總結下來就好,
另外,Vector和Stack這兩個集合類完全和ArrayList很像,除了Vector擴容默認是兩倍,是執行緒安全的,底層通過synchronized來實作的,Statck繼承了Vector,通過陣列實作了類似堆疊的資料結構,大家之后可以簡單掃一下就可以了,除了很老的原始碼代碼或者業務程式,現在基本不會使用這兩個集合類了,因為底層的synchronized鎖太影響性能了,
這一節你應該學到的一個思想就是,總結,當你按照脈絡看完原始碼后,畫完圖后,不能就此結束了,一定要總結一個要點和幾個要點出來,總結體現了做一件事的輸出結果,做任何事情都是樣的,比如運維管理IDC機柜機器,要出一個excel記錄每臺機器的采購時間,電池情況,硬碟情況等等,excel就是一個輸出結果,一個總結,
你在作業中,很多事情要以一個結果為結束才是最好的,檔案也好,流程點、里程碑也好,最好你要總結記錄下這個結果,相信你堅持這樣做會很有很多好處的,
金句甜點
金句甜點
除了今天知識,技能的成長,給大家帶來一個金句甜點,結束我今天的分享:堅持的三個秘訣之一視徑訓,
相信你肯定有會覺得過,堅持很難,可能你堅持1周還好,但是堅持1個月,1年,2年,5年,10年,一輩子…… 總有一個讓你感覺,好像真的堅持好難,但是其實很多時候不是堅持很難,而是你覺得值不值得的問題,這是根本原因,你可以仔細想想,是不是因為這個觀念所導致的,
除了要意識到這個觀念以外,到底怎么才能堅持一件事情呢?之后的文章我會給大家分享堅持的3個秘訣,首先第一個秘訣就是視徑訓,給大家舉個親身經歷吧,我畢業后作業了幾年,從一個瘦瘦的程式員,變成了帶游泳圈的瘦瘦程式員,于是有一天我決定要減脂塑形,想要恢復原來的肚子,不知道你們是不是也遇見過這種場景,于是我首先把我喜歡的一個偶像的有型的照片,有腹肌那種海報,貼在了家里一個比較隨意的地方,還附上了我自己的一個照片,那個畫面簡直了,,,我開始控制飲食,逐漸增加鍛煉強度和頻次,每次我不想運動的時候就會不經意的看到海報和我自己的照片,我再看看我的小肚子,就又開始鍛煉了,就著這樣不知不覺就堅持了1個月,果然有了效果,竟然體脂率下降了2%,體重下降了11斤,肚子小了一大圈,就是肌肉量沒啥變化,反正沒少就不錯了,接著,我就形成習慣了,再次在增加運動強度和頻次,因為我一直想著有一天程式員能有6塊或者8塊腹肌,那個場景好讓人向往啊,所以我一直在堅持著,
其實視徑訓的本質就是讓你感覺堅持的事情很值,你喜歡演講,你可以想象,有一天你站在上千人的聽眾面前,你聲情并茂的做了一場精彩的演講,那個場景就可以激勵你每天不斷的練習和學習,你想要晉升,你就不會睡懶覺,每天不會睡到自然醒,因為每當你起不了床的時候,你心中想象到一個場景,你晉升后可以給父母多寄些錢,給妻子、孩子買好的東西,可以減輕房貸或者車貸,可以幫助感恩之前幫助過的你的人等等,總有一個會讓你覺的值的理由,讓你堅持下去的,是不是?當然你喜歡學習,你也可以每周堅持看幾篇成長記來提升自己,相信成長會讓你變的更有價值,更有自信,
記住你人生中每走過的一步路,都不會被辜負的,總有一天又體現出來的,加油吧,各位!堅持吧,各位!
最后,你可以閱讀完原始碼后,在茶余飯后的時候問問同事或同學, 你也可以分享下,講給他聽聽,
歡迎大家在評論區留言和我交流,
本文由博客群發一文多發等運營工具平臺 OpenWrite 發布
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/320872.html
標籤:其他
