java ArrayList
talk is cheap , show me the code
说到数据结构,不由得就想起大学时的那本天书。没错,就是下面这本
不知道这本书有没有勾起大家一些美好的回忆呢?反正我只想到了大学里和基友们开黑的场景了。。。
^&^,好像扯远了。说回java。在java中,常用的数据结构,基本都已经给我们封装好了,比如说今天的主角ArrayList。常用的如表,队列,栈,树等。但是作为一名有志向的新世纪的伟大码农,怎么能只是了解他的API呢?当别人说起表的时候,你告诉他有add(),有remove(),有iterator()…这就好像女神和你说今晚去她家喝咖啡,你却说还要搬砖(这是注孤身的节奏啊!!!)
所以,下次女神问你ArrayList的时候,你就得手把手的教她实现一个简单的ArrayList:
private static final int DEFAULT_CAPACITY = 10; //默认容量
private int theSize;
private T[] theItems;
对于一个简易的ArrayList,上面的三个元素就足够了。从中可以看到,所谓ArrayList,其实是由一个数组来维护数据的。其他的操作如增删改查,都是立足于这个数组之上的。
当我们构建一个ArrayList的时候,我们需要做些什么呢?
构造
public MyArrayList(int var) { if (var > 0) { this.theItems = new Object[var]; } else { if (var != 0) { throw new IllegalArgumentException("Illegal capacity : " + var); } this.theItems = EMPTY_ELEMENTDATA; } }
很简单,按照指定的容量做构造。
相关的一些操作
add(int index, T var)
在add之前,需要首先检查index的合法性if (index < 0 || index >= size())
true 则抛出我们所熟知的ArrayIndexOutOfBoundsException,之后就可以做插入操作了:public boolean add(int index, T var) { check(index);//检查下标的合法性 if (theItems.length == theSize) { ensureCapacity(theSize >> 1 + 1);//数组扩容 } System.arraycopy(theItems, index, theItems, index + 1, theSize - index);//数组后移一位 theItems[index] = var; ++theSize; return true; }
remove(int index)
public T remove(int index) { check(index); T old = theItems[index]; int var = theSize - index - 1; //下标位置后面的元素个数 if (var > 0) { System.arraycopy(theItems, index + 1, theItems, index, var); } theItems[--theSize] = null; return old; }
同样的,在做remove操作时,首先也需要检查下标的合法性。然后检查是否是最后一个元素,即程序中的var变量,当var==0时,直接将其置为空即可,否则做移动操作。
至于其他的操作,可在一个神奇的地方找到我的代码。
说了这么多,简单说下基本是共识的东西吧。
- 作为以数组为主要实现的ArrayList,完全继承了数组的优缺点。所以擅长于get(),当做add()和remove时,如果是处于array的头部,则几乎需要挪动整个array,会比较消耗性能(所以当java在对数组做变动时,是使用的native方法,大家应该都懂得…)
- 当我们能预估我们要创建List的大小时,在实例化对象时指定它的size,这样,可以减少扩容所消耗的性能(要知道,一般的默认容量不会是什么靠谱的大小)