Java中為何要使用ArrayList
前言
當(dāng)我們用于獲取一組數(shù)據(jù)的時(shí)候,我們總是通過下面的格式定義變量。
private List<Tag> tags = new ArrayList<>();
我們熟悉的數(shù)組去哪了?
回顧數(shù)組
我們學(xué)習(xí)c語言,c++,會(huì)學(xué)到數(shù)組是存儲(chǔ)同類型的一組數(shù)據(jù)。后來學(xué)習(xí)指針,知道了兩種結(jié)構(gòu),鏈?zhǔn)浇Y(jié)構(gòu)與順序結(jié)構(gòu)。再后來學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)。知道了兩種結(jié)構(gòu)的優(yōu)缺點(diǎn)。
鏈?zhǔn)浇Y(jié)構(gòu)方便刪除,添加。
順序結(jié)構(gòu)方便查找。
但是我們?cè)趯?shí)際使用中逐漸感受到數(shù)組在使用上的缺點(diǎn)。不僅僅是在定義時(shí)就要規(guī)定數(shù)組大小。
我們通過一個(gè)實(shí)例來說明
Enemy[] enemys = new Enemy[3]; enemys[0].name = name1; enemys[1].name = name2; enemys[2].name = name3; // 通過名字擊殺對(duì)方 public void kill(string name) { for (Enemy enemy : this.enemys) { if (enemy.name === name) { enemy.death(); System.out.println("擊殺成功"); break; } } }
比如我們玩游戲,現(xiàn)在面前有三個(gè)敵人。我們可以通過名字擊殺對(duì)方(通過什么方法擊殺對(duì)方并不是我們的重點(diǎn))。
但是代碼有一些問題。如果我們總是傳入一個(gè)名字,比如name1,此時(shí)代碼總是會(huì)顯示擊殺成功,一個(gè)敵人只有一條命?,F(xiàn)在顯然與實(shí)際不符。如何解決呢。
這時(shí)我們想到了一個(gè)傳統(tǒng)的解決辦法。在enemy類里增加增加一個(gè)Boolean類型屬性alive,默認(rèn)值為true。此時(shí)改寫kill方法代碼。
public void kill(string name) { for (Enemy enemy : this.enemys) { if (enemy.name === name && enemy.alive === true) { enemy.death(); enemy.alive = false; System.out.println("擊殺成功"); break; } } }
就很好的解決了一個(gè)敵人可以被擊殺多次的bug。
但是,問題解決了,還有一些不足。
我們雖然不會(huì)顯示一個(gè)敵人多次擊殺成功。但是還是要搜尋一遍。有沒有更好的辦法呢。
ArrayList
如果我們能在成功擊殺的時(shí)候。能夠?qū)⑦@個(gè)敵人移除數(shù)組,并將數(shù)組長(zhǎng)度減一。將會(huì)變得完美。但是,通過數(shù)組是實(shí)現(xiàn)不了的。
這時(shí)ArrayList很好的解決了這個(gè)問題。
ArrayList并不是一個(gè)數(shù)組。而是Java函數(shù)庫的一個(gè)類。我們通過ArrayList來改寫一下我們的代碼。
ArrayList<Enemy> enemys = new ArrayList<Enemy>(); Enemy enemy1 = new Enemy(); enemy1.name = name1; enemys.add(enemy1); Enemy enemy2 = new Enemy(); enemy2.name = name2; enemys.add(enemy2); Enemy enemy3 = new Enemy(); enemy3.name = name3; enemys.add(enemy3); // 通過名字擊殺對(duì)方 public void kill(string name) { for (Enemy enemy : this.enemys) { if (enemy.name === name) { enemy.death(); this.enemys.remove(enemy); System.out.println("擊殺成功"); break; } } }
這時(shí),當(dāng)我們成功擊殺敵人時(shí),將敵人移除。就會(huì)使得下次遍歷時(shí)次數(shù)變少,并且也避免了重復(fù)殺死一個(gè)敵人的bug。
List與ArrayList
上邊的代碼中,我們?cè)诙x時(shí)是聲明的ArayList變量類型為ArrayList類型
ArrayList<Enemy> enemys = new ArrayList<Enemy>();
但是回到我們的實(shí)際項(xiàng)目中為什么是List類型呢
我們剛才說到ArrayList是一個(gè)類。我們看一下ArrayList類的繼承關(guān)系
而List是一個(gè)接口
public interface List<E> extends Collection<E> { }
所以說ArrayList是List的一個(gè)實(shí)現(xiàn)類。
而我們?cè)趯?shí)際項(xiàng)目中寫
List<Subject> usedSubjects = new ArrayList<>();
也就實(shí)現(xiàn)了以下格式代碼
接口 變量名 = new 接口實(shí)現(xiàn)類();
能夠?qū)崿F(xiàn)此寫法的一個(gè)原因就是面向?qū)ο蟮娜筇攸c(diǎn)之一——多態(tài)。
什么是多態(tài)?
舉個(gè)例子,對(duì)于以下Dog類
class Animal { } class Gog extends Animal { }
我們?cè)诙x對(duì)象時(shí)總是通過這樣來定義
Dog dog = new Dog();
而多態(tài)允許我們可以使用這種方式定義
Animal dog = new Dog ();
多態(tài)不僅支持子類與父類之間,也支持接口與他的實(shí)現(xiàn)類之間。
那么這么寫有什么好處呢?
List接口有多個(gè)實(shí)現(xiàn)類,現(xiàn)在你用的是ArrayList,也許哪一天你需要換成其它的實(shí)現(xiàn)類,如 LinkedList或者Vector等等,這時(shí)你只要改變這一行就行了: List list = new LinkedList(); 其它使用了list地方的代碼根本不需要改動(dòng)。
假設(shè)你開始用ArrayList alist = new ArrayList(), 這下你有的改了,特別是如果你使用了ArrayList實(shí)現(xiàn)類特有的方法和屬性。
以上就是Java中為何要使用ArrayList的詳細(xì)內(nèi)容,更多關(guān)于Java ArrayList的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java中實(shí)現(xiàn)Comparator接口和用法實(shí)例(簡(jiǎn)明易懂)
這篇文章主要介紹了Java中實(shí)現(xiàn)Comparator接口和用法實(shí)例(簡(jiǎn)明易懂),本文給出實(shí)現(xiàn)Comparator接口的實(shí)例和使用這個(gè)接口的代碼實(shí)例,需要的朋友可以參考下2015-05-05SpringBoot淺析緩存機(jī)制之Redis單機(jī)緩存應(yīng)用
在上文中我介紹了Spring Boot使用EhCache 2.x來作為緩存的實(shí)現(xiàn),本文接著介紹使用單機(jī)版的Redis作為緩存的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Java中的上下文加載器ContextClassLoader詳解
這篇文章主要介紹了Java中的上下文加載器ContextClassLoader詳解,ContextClassLoader是通過Thread.currentThread().getContextClassLoader()返回該線程上下文的ClassLoader,需要的朋友可以參考下2023-10-10SpringMVC實(shí)現(xiàn)Controller的三種方式總結(jié)
這篇文章主要介紹了SpringMVC實(shí)現(xiàn)Controller的三種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02???????Spring多租戶數(shù)據(jù)源管理 AbstractRoutingDataSource
本文技術(shù)了???????Spring多租戶數(shù)據(jù)源管理 AbstractRoutingDataSource,下文詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下2022-05-05Spring Boot+Shiro實(shí)現(xiàn)一個(gè)Http請(qǐng)求的Basic認(rèn)證
本文向向大家仔細(xì)的介紹了如何使用Shiro實(shí)現(xiàn)一個(gè)Http請(qǐng)求的Basic認(rèn)證,有此需求的朋友可以參考下本文2021-06-06Java攔截器Interceptor實(shí)現(xiàn)原理及代碼示例
本文詳細(xì)講解了Java攔截器Interceptor實(shí)現(xiàn)原理及代碼示例,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12