【干貨】用大白話聊聊JavaSE — ArrayList 深入剖析和Java基礎知識詳解(一)

Paste_Image.png

對Java程序開發(fā)而言脯爪,ArrayList 的使用頻率是非常高的癣朗,尤其在進行 JavaWeb 開發(fā)的時候,ArrayList 和 HashMap 這兩個類浇辜,相信你一定不會陌生朋魔,因為天天都在用嘛岖研。

本系列對 ArrayList 做一個解析,同時把Java基礎知識個串連進去警检。一開始我會對如何使用 ArrayList 做一個簡要的說明孙援,然后,我們來仿照 ArrayList 封裝一個自己的集合框架MyList扇雕,通過練習拓售,來一步一步猜想ArrayList 可能的實現方式。

最后镶奉,深入到ArrayList 的源碼進行解讀础淤。

為什么要學習源碼?

很簡單哨苛,一個知道源碼的人和一個不知道源碼的人鸽凶,雖然都能使用 ArrayList ,但是建峭,他們在使用的時候玻侥,心態(tài)是完全不一樣的。

只有當你深入了源碼亿蒸,然后你才會對它的一些細節(jié)有更充分的認識凑兰。這是一本萬利的事情。

當然边锁,對于初學者姑食,還是盡量以使用為主,因為源碼的話砚蓬,畢竟有一定的難度矢门。如果一味地追求這些東西,可能會大大降低自己的學習興趣和熱情灰蛙。

1祟剔、 ArrayList 概述


副本難度:一顆星
經驗值:500



首先來看一下文檔,

Paste_Image.png

<h5>
All Implemented Interfaces:
Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess
</h5>

<p>
從圖中可以看到摩梧,ArrayList 實現了Iterable接口物延,這個接口表示一種迭代的能力。
</p>

既然是ArrayList仅父,那么肯定和 List 有關叛薯,所以它果然繼承了List接口。

接口的知識點在這里就用上了笙纤。

其他接口我們暫且不談耗溜,先繼續(xù)。

然后省容,我們看一下官方對ArrayList 做出的說明抖拴。

文檔中有這么一句:

Resizable-array implementation of the List interface.

這句話是說,ArrayList 是對List接口的一個實現腥椒,實現方式是利用一個可改變尺寸的數組阿宅,也就是說,它的底層就是一個數組笼蛛。而且是可改變尺寸的數組洒放,說明這個數組是動態(tài)的。

哦滨砍,難怪它叫ArrayList 往湿,Array就是數組的意思,那么它肯定和數組有關惋戏。

**Implements all optional list operations, and permits all elements, including null. **

ArrayList 實現了list接口的所有方法领追,并且允許空元素。

前半句是肯定的日川,因為在Java中蔓腐,如果一個類實現了一個接口,那么就必須要重寫該接口里所有的抽象方法龄句。

我們知道回论,接口里只有方法的聲明,沒有方法的實現分歇。

我對接口的理解傀蓉,總結以后就只有一句話:

Java類實現接口,就是給這個類本身添加了一個新的身份职抡。

ArrayList是一個類葬燎,那么它的身份就是ArrayList,你問他“你叫什么名字呀?”谱净,他肯定會毫不猶豫地告訴你窑邦,“我叫ArrayList!”壕探。

白天冈钦,我們大家都以為它是ArrayList,結果到了夜晚李请。

ArrayList竟然搖身一變瞧筛,成為了Iterable!

原來导盅,ArrayList實現了Iterable较幌,所以它也就擁有了Iterable的身份。

接口其實就是這個意思白翻。網上對接口的解釋眾說紛紜乍炉,反正我總結下來就是這么一句話,也不想搞那么復雜了嘁字。

ArrayList不僅有Iterable的身份恩急,還擁有其他好幾種身份,比如List纪蜒,Collection等衷恭。

這個情況也叫作多態(tài)。

新建一個測試類纯续。

public class TestArrayList1 {

    public static void main(String[] args) {
        
    }
}

現在我新建一個ArrayList類的實例

ArrayList list = new ArrayList();

這肯定是沒問題的随珠。

文檔上說,ArrayList 實現了Iterable接口猬错,那么也就是說窗看,它的另一個身份是Iterable。

所以倦炒,我這樣寫是不是也沒有問題啊显沈。

Iterable iterable = new ArrayList();

就好像白天是普通的上班族,一旦到了夜晚逢唤,就拉讯。。鳖藕。

總之魔慷,

Iterable iterable = new ArrayList();

這句話的含義就是說,它原來是普通的ArrayList著恩,一旦情況需要院尔,就變身成為Iterable蜻展。

好了,既然變成了 Iterable 邀摆,那么它是不是也就擁有了 Iterable 的能力纵顾?

我們來看一下 Iterable 有哪些方法?

去除繼承自Object類的方法不談隧熙,Iterable 只有一個方法片挂,就是 iterator()

Paste_Image.png

它返回的是一個 Iterator 幻林,這是一個迭代器贞盯。

通過這個迭代器,我們是不是就可以遍歷 ArrayList 中所有的數據了呀沪饺?

首先躏敢,我們需要一個迭代對象:

Iterable iterable = new ArrayList();
Iterator it = iterable.iterator();

當然,這個例子中整葡,ArrayList里面沒有數據件余。

現在思考一個問題,是不是我非得把 ArrayList 對象改變成 Iterable 身份遭居,才可以調用 iterator() 方法呢啼器?

當然不是了,ArrayList 有一個身份是 Iterable 俱萍,所以它具有 Iterable 的所有能力(方法)端壳,這沒問題。那么難道 ArrayList 不變身枪蘑,就沒有 Iterable 的能力了嗎损谦?

答案自然是否定的。

一個小說家如果有一天轉行去寫代碼了岳颇,那么你覺得他還會不會寫小說呢照捡?

肯定會嘛,這沒有什么好懷疑的话侧。

所以栗精,代碼這么寫是不是也沒關系?

ArrayList list = new ArrayList();

for (int i = 0; i < 100; i++) {
    list.add(i);
}

Iterator it = list.iterator();

循環(huán)輸出

while(it.hasNext()){
    System.out.println(it.next());
}
Paste_Image.png

總結一下瞻鹏,ArrayList 它只要實現 Iterable 接口悲立,那么它就必須要擁有 Iterable 規(guī)定的所有能力,也就是方法乙漓。而接口中级历,我們知道它里面只有方法的聲明,沒有方法的實現叭披,所以 ArrayList 需要實現這些方法寥殖,實現接口就是這么個意思玩讳。

2、 ArrayList常用方法


副本難度:三顆星
經驗值:800

2.1嚼贡、 屬性和方法的調用問題

在調用ArrayList的方法之前熏纯,我們需要先獲得一下ArrayList的實例對象,除了靜態(tài)方法粤策,其他所有的方法武福,都只能由對象來調用搜锰。

ArrayList是一個類,我更愿意把它稱為一個** 數據模板**。它只是一個模板而已赔蒲,不是一個實實在在的對象脖阵,這一點首先要確定烫葬。

就好像工廠生產一個產品牺陶,首先是不是要有一個模板和設計圖紙,這個模板決定了你這個產品是一種怎樣的形狀愈魏,以及可能會具備哪些功能觅玻?圖紙則決定了功能的具體實現。

比如生成一部手機培漏,模板開出來就是一個扁平的長方體的樣子溪厘,可是光有模板還不行,你還得規(guī)定它的一些具體細節(jié)牌柄。

這些細節(jié)就好比是Java類的構造方法畸悬,以及其他的一些方法實現。

但是友鼻,你光給客戶模板和圖紙行嗎傻昙?

一般來說是不行的。

至于靜態(tài)方法彩扔,我們知道妆档,我們調用靜態(tài)方法的時候,不需要先生成一個實例虫碉,可以通過類名直接調用贾惦。

這就相當于,在弄模版的時候敦捧,這些功能就已經定制在里面了须板。

你買手機的時候,里面不是經常有一些內置的應用嗎兢卵?有些刪都刪不掉习瑰,這不就相當于靜態(tài)方法嗎?

(我只是舉一個例子啊秽荤,你不要非得較真說我可以ROOT一下疤鹧佟)

如果模板里面已經有了一些做好的功能柠横,今后任何根據這個模具生成出來的產品也自帶了這些功能。

如果模板里面已經做好了一些功能课兄,那么我的確可以使用這個模板牍氛,而不需要真正拿到一個產品。

比如生產一部手機烟阐,它的模板里面已經做好了一個手電筒的功能搬俊,那么,你即便不給我一個真正的產品蜒茄,僅僅給我一個模板唉擂,我是不是也可以用它的手電筒功能呢?

這就是靜態(tài)方法扩淀。

所以我們常說楔敌,靜態(tài)方法和靜態(tài)屬性為所有實例共用,不就是這個道理嗎驻谆?

所以,正常情況下庆聘,我們調用一個類的非靜態(tài)方法胜臊,是不是必須要先new一個對象?

好的伙判,我們現在來 根據 ArrayList 模板生產一個 ArrayList 產品象对。

這樣,我們才能調用它里面所有的非私有方法宴抚。

怎么生產呢勒魔,是不是new一下就可以啦?

ArrayList  arrayList = new ArrayList(); 

2.2菇曲、 add方法

ArrayList是一個集合冠绢,既然是一個集合,那么它肯定是可以往里頭添東西的常潮。

怎么往里面添弟胀,用add,用add方法往里面加喊式。

arrayList.add("HelloWorld"); //添加一個字符串
arrayList.add(new Integer(100));//添加一個Integer類型的數字

add的參數就是一個object孵户,這就是多態(tài),多態(tài)就是多種形態(tài)岔留,多種身份的意思夏哭。object可以有多種形態(tài)。它可以是String献联,也可以是Integer竖配,還可以是用戶自定義的類型厕吉。

這里是不是又多態(tài)了。械念。头朱。

這就是多態(tài)的一個用法。

2.3龄减、 get 方法

既然能夠往里面添加東西项钮,是不是肯定還要拿出來啊。

怎么拿出來希停,用get方法拿出來烁巫,而且一次只能拿一個。不要多拿哦宠能。

get 方法需要傳入一個 int 類型的數字亚隙,這個數字就是元素對應的下標。

我們剛才第一個放進去的是 "HelloWorld" 违崇,一個字符串阿弃。那么對應的下標就是0 。

第二個放進去的是new Integer(100)羞延,這是一個Integer對象渣淳,是一個實實在在的東西了。那么對應的下標就是1 伴箩。

現在入愧,我取出第1個元素,應該是100嗤谚。

試試看

Integer i = arrayList.get(1);
Paste_Image.png

報錯了棺蛛,因為 get 方法返回的是一個Object對象,而我們拿Integer 去接巩步,就出問題了旁赊。

這是咋回事呢?

很簡單渗钉,比如張三是一個醫(yī)生彤恶,同時他還擁有一個人類的身份,可并不是所有的人類都是醫(yī)生蚌佟声离?

注意我下面分析的用詞,能幫助你理解瘫怜。

同理术徊,Integer 是一個整數類型,同時它還擁有一個Object的身份鲸湃,可并不是所有的 Object 都是Integer 霸獭子寓?

同接口一樣,A繼承B笋除,可以看成A同時擁有了B的身份斜友。

如果A繼續(xù)保持A的身份,那么它不僅擁有自己本身的能力垃它,也擁有B的能力鲜屏。只要A愿意,他完全可以展現B的能力国拇。

如果A變身成為了B洛史,那么它肯定不希望別人知道他是A。

就好比雖然他知道他可以變身成為奧特曼酱吝,但是一般情況下也殖,他都不愿意曝露自己的身份。

所以如果A變身成為了B务热,那么A就只會使用B的能力忆嗜,同時隱藏他本身的能力。

如果你是初學者陕习,請仔細體會一下這其中的韻味霎褐。慢慢地,你就會對多態(tài)有一個更深入的理解该镣。一段時間后,你再重新去看以前寫的代碼响谓,會有不一樣的感覺损合。

再舉一個例子,幫助你理解娘纷。

我 new 一個 ArrayList :(在eclipse中)

ArrayList  arrayList = new ArrayList();

換行嫁审,寫上arrayList 。

我直接在arrayList 右邊加一個點赖晶,然后會有提示:

Paste_Image.png

這些都是它可以調用的方法和屬性律适,哇,這么多遏插。

如果我這樣寫呢捂贿?

Object  arrayList = new ArrayList();

我也在arrayList 右邊加一個點

Paste_Image.png

不好意思,你現在只能調用 Object 類的屬性和方法了胳嘲。

嗯厂僧,再體會一下。

初學者在面向對象方面的理解總是會走彎路了牛,如果你能把這些東西理清颜屠,對今后的學習會有巨大的好處辰妙。

繼續(xù)。

我們這里就強轉一下吧甫窟,因為我們知道 index 為1的元素是一個Integer類型的密浑。

Integer i = (Integer) arrayList.get(1);
System.out.println(i);

結果

Paste_Image.png

好的,是正確的粗井。

2.4尔破、 remove 方法

remove 方法可以刪除集合中的元素,ArrayList給我們提供了很多刪除元素的方法背传。

Paste_Image.png

我們這里先看一下第一個方法呆瞻。

這是通過數組下標來刪除某一個特定的元素,我們剛才給ArrayList添加了兩個元素径玖,下標分別為 0,1 痴脾,那么,如果我刪除第0個元素梳星,會怎么樣呢赞赖?

首先,ArrayList的列表長度會不會改變冤灾?

我們可以通過size()方法來獲取ArrayList當前的列表長度前域。

測試:

arrayList.remove(0);
System.out.println(arrayList.size());

打印出來是1,看來的確是影響長度了韵吨。

2.5匿垄、 toArray 方法

這個方法可以將ArrayList轉換成一個Object數組。

例:

Object[] objs = arrayList.toArray();

for (int i = 0; i < objs.length; i++) {
    System.out.println(objs[i].toString());
}

需要注意的是归粉,哪怕你給ArrayList全部添加Integer類型的元素椿疗,也不能采用這樣的代碼:

Integer[] objs = (Integer[]) arrayList.toArray();

這是錯誤的,雖然編譯的時候不會報錯糠悼,但是運行無法通過届榄。

因為ArrayList的add方法可以添加任意類型的參數,Java運行機制無法獲知ArrayList中的元素是否可以都強制轉換為你指定的類型倔喂。所以這種寫法是不被允許的铝条。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市席噩,隨后出現的幾起案子班缰,更是在濱河造成了極大的恐慌,老刑警劉巖班挖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲁捏,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機给梅,發(fā)現死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門假丧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人动羽,你說我怎么就攤上這事包帚。” “怎么了运吓?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵渴邦,是天一觀的道長。 經常有香客問我拘哨,道長谋梭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任倦青,我火速辦了婚禮瓮床,結果婚禮上,老公的妹妹穿的比我還像新娘产镐。我一直安慰自己隘庄,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布癣亚。 她就那樣靜靜地躺著丑掺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪述雾。 梳的紋絲不亂的頭發(fā)上街州,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音玻孟,去河邊找鬼菇肃。 笑死,一個胖子當著我的面吹牛取募,可吹牛的內容都是我干的。 我是一名探鬼主播蟆技,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼玩敏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了质礼?” 一聲冷哼從身側響起旺聚,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眶蕉,沒想到半個月后砰粹,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡造挽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年碱璃,在試婚紗的時候發(fā)現自己被綠了弄痹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡嵌器,死狀恐怖肛真,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情爽航,我是刑警寧澤蚓让,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站讥珍,受9級特大地震影響历极,放射性物質發(fā)生泄漏。R本人自食惡果不足惜衷佃,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一趟卸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纲酗,春花似錦衰腌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吮螺,卻和暖如春饶囚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸠补。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工萝风, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人紫岩。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓规惰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泉蝌。 傳聞我的和親對象是個殘疾皇子歇万,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容