ArrayList实现

来源:互联网 发布:知乎经典钓鱼贴 编辑:程序博客网 时间:2024/05/16 06:22

ArrayList

List接口

package changsheng.algorithms.list;import java.util.Iterator;public interface List<E> {public boolean add(E e);public void add(E e,int i);public E remove(int i);public boolean remove(E e);public void removeAll();public E set(int i,E e );public E get(int i);public int indexOf(E e);int size();boolean contains(E e);boolean isEmpty();Iterator<E> iterator();public E[] toArray();}

实现ArrayList采用了测试驱动开发的模式,首先书写了Unit Test,然后再进行开发。

JUnit Test

package changsheng.algorithms.list;import static org.junit.Assert.*;import org.junit.Test;public class ArrayListTest {@Testpublic void testAddAndGet() {/******************************************************/List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}for (int i = 0; i < 10; i++) {assertEquals(String.valueOf(i), list.get(i));}}@Testpublic void testSize() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}assertEquals(10, list.size());}@Testpublic void testAddTail() {/* 测试边缘情况,在末尾添加元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}String expected = String.valueOf(11);list.add(expected);assertEquals(expected, list.get(10));}@Testpublic void testAddFront() {/* 测试边缘情况,在表头添加元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.add(String.valueOf(-1), 0);assertEquals(-1, Integer.parseInt(list.get(0)));}@Testpublic void testRemoveAll() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.removeAll();assertEquals(0, list.size());}@Testpublic void testRemove() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}String number = list.remove(0);int expectedValue = 0;int expectedSize = 9;assertEquals(expectedValue, Integer.parseInt(number));assertEquals(expectedSize, list.size());}@Testpublic void testRemoveFront() {/* 测试边缘情况,在表头移除元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.remove(0);for (int i = 0; i < 9; i++) {int expected = i + 1;assertEquals(expected, Integer.parseInt(list.get(i)));}}@Testpublic void testRemoveTail() {/* 测试边缘情况,在末尾移除元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.remove(9);int expectedSize = 9;int expectedNumber = 8;assertEquals(expectedNumber, Integer.parseInt(list.get(8)));assertEquals(expectedSize, list.size());}@Testpublic void testSet() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}String number = list.set(4, String.valueOf(-1));int expectedNumberOld = 4;int expectedNumberNew = -1;assertEquals(expectedNumberOld, Integer.parseInt(number));assertEquals(expectedNumberNew, Integer.parseInt(list.get(4)));}@Testpublic void testIndexOfFirst() {/* 测试边缘情况,第一个元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}int expecteds = 0;int actuals = list.indexOf(list.get(0));assertEquals(expecteds, actuals);}@Testpublic void testIndexOfLast() {/* 测试边缘情况,最后一个元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}int expecteds = 9;int actuals = list.indexOf(list.get(9));assertEquals(expecteds, actuals);}@Testpublic void testIndexOfNo() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}int expecteds = -1;int actuals = list.indexOf(new String());assertEquals(expecteds, actuals);}@Testpublic void testContains() {/* 测试边缘情况,最后一个元素 */List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}int expecteds = 9;int actuals = list.indexOf(list.get(9));assertEquals(expecteds, actuals);}@Testpublic void testContainsNo() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}boolean expecteds = false;boolean actuals = list.contains(new String());assertEquals(expecteds, actuals);}@Testpublic void testToArray() {List<String> list = new ArrayList<String>();int[] actuals = new int[10];for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));actuals[i] = i;}int[] expecteds = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };assertArrayEquals(expecteds, actuals);}@Test(expected=IndexOutOfBoundsException.class)public void testAddException1() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.add(new String(), -1);}@Test(expected=IndexOutOfBoundsException.class)public void testAddException2() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.add(new String(), 10);}@Test(expected=IndexOutOfBoundsException.class)public void testRemoveException1() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.remove( -1);}@Test(expected=IndexOutOfBoundsException.class)public void testRemoveException2() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.remove( 10);}@Test(expected=IndexOutOfBoundsException.class)public void testSetException1() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.set(-1,new String());}@Test(expected=IndexOutOfBoundsException.class)public void testSetException2() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.set(10,new String());}@Test(expected=IndexOutOfBoundsException.class)public void testGetException1() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.get(-1);}@Test(expected=IndexOutOfBoundsException.class)public void testGetException2() {List<String> list = new ArrayList<String>();for (int i = 0; i < 10; i++) {list.add(String.valueOf(i));}list.get(10);}}

ArrayList实现


在JDK源码中,ArrayList对null元素进行了处理,感兴趣的可以查看JDK源码。
package changsheng.algorithms.list;import java.util.Arrays;import java.util.Iterator;public class ArrayList<E> implements List<E> {private E[] elementData;private int elementCount;private int DEFAULT_SIZE = 10;@SuppressWarnings("unchecked")public ArrayList() {elementData = (E[]) new Object[DEFAULT_SIZE];elementCount = 0;}/** * 在末尾添加元素e *  * @param e *            待添加的元素 * @return 如果添加成功返回true */@Overridepublic boolean add(E e) {ensureCapacity(elementCount + 1);elementData[elementCount++] = e;return true;}/** * 将e元素添加到index位置上 *  * @param e *            待添加的元素 * @param index *            待添加的索引位置 */@Overridepublic void add(E e, int index) {if (index < 0 || index > elementCount - 1) {throw new IndexOutOfBoundsException();}ensureCapacity(elementCount + 1);for (int i = elementCount - 1; i > index; i--) {elementData[i] = elementData[i - 1];}elementCount++;elementData[index] = e;}/** * 移除索引位置为index的元素,并返回该元素 */@Overridepublic E remove(int index) {if (index < 0 || index >= elementCount) {throw new IndexOutOfBoundsException();}E oldValue = elementData[index];for (int i = index; i < elementCount - 1; i++) {elementData[i] = elementData[i + 1];}elementData[--elementCount] = null;return oldValue;}/** * 移除e元素 *  * @param e *            待移除的元素 * @return 如果找到该元素成功删除返回true,否则返回false */@Overridepublic boolean remove(E e) {if (elementCount == 0) {return false;}for (int i = 0; i < elementCount; i++) {if (e.equals(elementData[i])) {remove(i);return true;}}return false;}/** * 移除所有元素 */@SuppressWarnings("unchecked")@Overridepublic void removeAll() {/** * JDK源码中clear方法中的清空方式为将数组中的元素都赋值为null, * 让GC进行回收,并没有改变数组的大小。 *  * 在此处的方法只是将elementData赋值为一个新的默认数组。 */elementData = (E[]) new Object[DEFAULT_SIZE];elementCount = 0;}/** * 将index位置的元素设置为e,并返回原始元素 *  * @param index *            索引位置 * @param e *            元素 * @return 返回原始元素 */@Overridepublic E set(int index, E e) {if (index < 0 || index >= elementCount) {throw new IndexOutOfBoundsException();}E oldValue = elementData[index];elementData[index] = e;return oldValue;}/** * 获取index位置的元素 */@Overridepublic E get(int index) {if (index < 0 || index >= elementCount) {throw new IndexOutOfBoundsException();}return elementData[index];}/** * 获取待寻找元素的索引 *  * @param e *            待寻找的元素 * @return 如果存在返回待寻找元素的索引,否则返回-1 */@Overridepublic int indexOf(E e) {for (int i = 0; i < elementCount; i++) {if (e.equals(elementData[i])) {return i;}}return -1;}/** * 返回元素 */@Overridepublic int size() {return elementCount;}/** * 判断是否包含此元素 *  * @param e *            待寻找的元素 * @return 如果找到该元素返回true,否则返回false */@Overridepublic boolean contains(E e) {return indexOf(e) >= 0;}/** * 返回迭代器 */@Overridepublic Iterator<E> iterator() {return null;}/** * 返回对象数组 */@Overridepublic E[] toArray() {return Arrays.copyOfRange(elementData, 0, elementCount - 1);}/** * 扩展容器数组 *  * @param newLength *            长度 */private void ensureCapacity(int newLength) {if (newLength == elementData.length) {/* 对其进行2倍长度扩展 */elementData = Arrays.copyOf(elementData, elementData.length * 2);}}/** * 列表是否为空 */@Overridepublic boolean isEmpty() {return elementCount == 0;}}