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

以上就是Java中为何要使用ArrayList的详细内容,更多关于Java ArrayList的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java如何把数组转换为ArrayList

    这篇文章主要介绍了Java如何把数组转换为ArrayList,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 翻译自:How to Convert Array to ArrayList in Java? 本文分析了Stack Overflow上最热门的的一个问题的答案,提问者获得了很多声望点,使得他得到了在Stack Overflow上做很多事情的权限.这跟我没什么关系,我们还是先看看这个问题吧. 这个问题是"在Java中怎样把数组转换为Arra

  • Java ArrayList add(int index, E element)和set(int index, E element)两个方法的说明

    一般使用List集合,估计都是使用这个ArrayList,一般呢也就是简单遍历数据和存储数据. 很少使用到add(int index, E element)和set(int index, E element)两个方法. 这两个方法,乍一看,就是在指定的位置插入一条数据. 区别: set()是更新,更新指定下标位置的值. add()是添加,区别于一般的add(E e),这个就是有个位置的概念,特殊位置之后的数据,依次往后移动就是了. 然后,看下面代码.来看看陷阱. 就算是,你知道了上面的内容,也不

  • Java源码解析ArrayList及ConcurrentModificationException

    本文基于jdk1.8来分析ArrayList的源码 首先是主要的成员变量. /** * Default initial capacity. **/ private static final int DEFAULT_CAPACITY = 10; /** * Shared empty array instance used for empty instances. **/ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * Shar

  • Java源码解析CopyOnWriteArrayList的讲解

    本文基于jdk1.8进行分析. ArrayList和HashMap是我们经常使用的集合,它们不是线程安全的.我们一般都知道HashMap的线程安全版本为ConcurrentHashMap,那么ArrayList有没有类似的线程安全的版本呢?还真有,它就是CopyOnWriteArrayList. CopyOnWrite这个短语,还有一个专门的称谓COW. COW不仅仅是java实现集合框架时专用的机制,它在计算机中被广泛使用. 首先看一下什么是CopyOnWriteArrayList,它的类前面

  • Java用Arrays.asList初始化ArrayList实例方法

    Java中使用Arrays.asList初始化ArrayList package xiaoling; import java.util.Arrays; import java.util.ArrayList; import java.util.List; public class ListTest{ public static void main(String[] args){ List<List<Integer>> list = new ArrayList<>(); f

  • Java ArrayList.add 的实现方法

    ArrayList是平时相当常用的List实现, 其中boolean add(E e) 的实现比较直接: /** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ public boole

  • Java 数组ArrayList常用语法详解

    恶补基础,记录一下数组ArrayList的常用语法 1.导入 import java.util.ArrayList; 2.定义数组list ArrayList<类名> list = new ArrayList<类名>(); 不能是基本类型,必须是类 3.获取集合大小 size() 4.存入数据 add(Object object);从下标0开始加入 add(int idx,Object object);将object插入索引为idx的位置,idx<=list.size();

  • 详解Java ArrayList类

    ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素. ArrayList 继承了 AbstractList ,并实现了 List 接口. ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下: import java.util.ArrayList; // 引入 ArrayList 类 ArrayList<E> objectName =new ArrayList<>(); // 初始化 E

  • Java中ArrayList在foreach里remove的问题详析

    前言 ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和IList接口 灵活的设置数组的大小 都说ArrayList在用foreach循环的时候,不能add元素,也不能remove元素,可能会抛异常,那我们就来分析一下它具体的实现.我目前的环境是Java8. 有下面一段代码: public class TestForEachList extends BaseTests { @Test

  • 对Java ArrayList的自动扩容机制示例讲解

    注意: 不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力,ArrayList会增强自身的存储能力,已达到存储新元素的要求 ArrayList:本质通过内部维护的数组对象进行数据存储 ①:分析ArrayList的add(E)方法 public boolean add(E e) { ensureCapacityInternal(size + 1); /

  • java ArrayList.remove()的三种错误用法以及六种正确用法详解

    java集合中,list列表应该是我们最常使用的,它有两种常见的实现类:ArrayList和LinkedList.ArrayList底层是数组,查找比较方便:LinkedList底层是链表,更适合做新增和删除.但实际开发中,我们也会遇到使用ArrayList需要删除列表元素的时候.虽然ArrayList类已经提供了remove方法,不过其中有潜在的坑,下面将介绍remove方法的三种错误用法以及六种正确用法. 1.错误用法 1.1.for循环中使用remove(int index),列表从前往后

随机推荐