为何咱们使用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实现类特有的方法和属性。

相关文章
相关标签/搜索