爲何咱們使用ArrayList?

前言

當咱們用於獲取一組數據的時候,咱們老是經過下面的格式定義變量。c++

private List<Tag> tags = new ArrayList<>();

咱們熟悉的數組去哪了?數組

回顧數組

咱們學習c語言,c++,會學到數組是存儲同類型的一組數據。後來學習指針,知道了兩種結構,鏈式結構與順序結構。再後來學習數據結構。知道了兩種結構的優缺點。數據結構

鏈式結構方便刪除,添加。
順序結構方便查找。函數

可是咱們在實際使用中逐漸感覺到數組在使用上的缺點。不單單是在定義時就要規定數組大小。學習

咱們經過一個實例來講明this

Enemy[] enemys  = new Enemy[3];

enemys[0].name = name1;
enemys[1].name = name2;
enemys[2].name = name3;

// 經過名字擊殺對方
public void kill(string name) {
    for (Enemy enemy : this.enemys) {
        if (enemy.name === name) {
            enemy.death();
            System.out.println("擊殺成功");
            break;
        }
    }
}

好比咱們玩遊戲,如今面前有三個敵人。咱們能夠經過名字擊殺對方(經過什麼方法擊殺對方並非咱們的重點)。
可是代碼有一些問題。若是咱們老是傳入一個名字,好比name1,此時代碼老是會顯示擊殺成功,一個敵人只有一條命。如今顯然與實際不符。如何解決呢。
這時咱們想到了一個傳統的解決辦法。在enemy類裏增長增長一個Boolean類型屬性alive,默認值爲true。此時改寫kill方法代碼。spa

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;
        }
    }
}

就很好的解決了一個敵人能夠被擊殺屢次的bug。
可是,問題解決了,還有一些不足。指針

咱們雖然不會顯示一個敵人屢次擊殺成功。可是仍是要搜尋一遍。有沒有更好的辦法呢。code

ArrayList

若是咱們能在成功擊殺的時候。可以將這個敵人移除數組,並將數組長度減一。將會變得完美。可是,經過數組是實現不了的。對象

這時ArrayList很好的解決了這個問題。

ArrayList並非一個數組。而是Java函數庫的一個類。咱們經過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);

// 經過名字擊殺對方
public void kill(string name) {
    for (Enemy enemy : this.enemys) {
        if (enemy.name === name) {
            enemy.death();
            this.enemys.remove(enemy);
            System.out.println("擊殺成功");
            break;
        }
    }
}

這時,當咱們成功擊殺敵人時,將敵人移除。就會使得下次遍歷時次數變少,而且也避免了重複殺死一個敵人的bug。

List與ArrayList

上邊的代碼中,咱們在定義時是聲明的ArayList變量類型爲ArrayList類型

ArrayList<Enemy> enemys = new ArrayList<Enemy>();

可是回到咱們的實際項目中爲何是List類型呢

咱們剛纔說到ArrayList是一個類。咱們看一下ArrayList類的繼承關係

image.png

而List是一個接口

public interface List<E> extends Collection<E> {
}

因此說ArrayList是List的一個實現類。
而咱們在實際項目中寫

List<Subject> usedSubjects = new ArrayList<>();

也就實現瞭如下格式代碼

接口 變量名 = new 接口實現類();

可以實現此寫法的一個緣由就是面向對象的三大特色之一——多態。
什麼是多態?
舉個例子,對於如下Dog類

class Animal {
}

class Gog extends Animal {
}

咱們在定義對象時老是經過這樣來定義

Dog dog = new Dog();

而多態容許咱們可使用這種方式定義

Animal dog = new Dog ();

多態不只支持子類與父類之間,也支持接口與他的實現類之間。

那麼這麼寫有什麼好處呢?

List接口有多個實現類,如今你用的是ArrayList,也許哪一天你須要換成其它的實現類,如 LinkedList或者Vector等等,這時你只要改變這一行就好了: List list = new LinkedList(); 其它使用了list地方的代碼根本不須要改動。 

假設你開始用ArrayList alist = new ArrayList(), 這下你有的改了,特別是若是你使用了ArrayList實現類特有的方法和屬性。

相關文章
相關標籤/搜索