乐趣区

关于java:为什么我们使用ArrayList

前言

当咱们用于获取一组数据的时候,咱们总是通过上面的格局定义变量。

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

咱们相熟的数组去哪了?

回顾数组

咱们学习 c 语言,c++,会学到数组是存储同类型的一组数据。起初学习指针,晓得了两种构造,链式构造与程序构造。再起初学习数据结构。晓得了两种构造的优缺点。

链式构造不便删除,增加。
程序构造不便查找。

然而咱们在理论应用中逐步感触到数组在应用上的毛病。不仅仅是在定义时就要规定数组大小。

咱们通过一个实例来阐明

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 办法代码。

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。
然而,问题解决了,还有一些有余。

咱们尽管不会显示一个敌人屡次击杀胜利。然而还是要搜查一遍。有没有更好的方法呢。

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 类的继承关系

而 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 实现类特有的办法和属性。

退出移动版