ArrayList的简单实现
Posted 法海你懂不
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList的简单实现相关的知识,希望对你有一定的参考价值。
ArrayList是List接口的一个可变大小的数组的实现
ArrayList的内部是使用一个Object对象数组来存储元素的
初始化ArrayList的时候,可以指定初始化容量的大小,如果不指定,就会使用默认大小,为10
当添加一个新元素的时候,首先会检查容量是否足够添加这个元素,如果够就直接添加,如果不够就进行扩容,扩容为原数组容量的1.5倍
当删除一个元素的时候,会将数组右边的元素全部左移
ArrayList使用的存储的数据结构是Object的对象数组,因为是数组,所有具有数组普遍的优点,比如随机存取快,删除操作比较慢等。
这里尝试着实现一个基本的CustomArrayList
,主要参考Java8的ArrayList实现。
定义ArrayList类
import java.util.*;
public class CustomArrayList<E>
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = ;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = ;
transient Object[] elementData;
private int size;
public CustomArrayList(int initialCapacity)
if (initialCapacity > 0)
this.elementData = new Object[initialCapacity];
else if (initialCapacity == 0)
this.elementData = EMPTY_ELEMENTDATA;
else
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
public CustomArrayList()
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
其中最基本的是elementData
属性,在类里面的所有数组都是存储在这个属性里面。如果创建CustomArrayList
的时候,没有确定数组大小,则初始化elementData
为空;如果创建CustomArrayList
已经确定了数组大小,那么new一个指定大小的数组即可。
add 操作
向CustomArrayList
添加元素也是比较简单的,首先预判断elementData
的分配的空间长度是否能够新添加一个元素,如果可以,那么将元素添加在elementData
有效元素的末尾便可;如果elementData
的分配的空间长度不足以添加一个元素,那么便在原来空间长度的基础上添加原空间长度的一半大小。
public boolean add (E e)
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
private void ensureCapacityInternal(int minCapacity)
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity - elementData.length > 0)
grow(minCapacity);
private void grow(int minCapacity)
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
remove操作
删除CustomArrayList
中的元素可以分为两种,一种是删除指定下标的元素,另一种是删除指定值的元素。
删除指定下标的元素
首先判断给定的下标是否合法,如果不合法,那么抛出异常;如果合法,那么只需要使用指定下标后面的元素依次覆盖掉指定下标的值便可。
public E remove(int index)
if (index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size);
E oldValue = (E)elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
elementData[--size] = null;
return oldValue;
删除指定值的元素
这种方式的删除需要遍历一次数组,当找到数组中的指定值使,记录下标,然后使用该下标后面的值依次覆盖掉该下标的值便可。
public boolean remove(Object o)
if (o == null)
for (int index = 0; index < size; index++)
if (elementData[index] == null)
fastRemove(index);
return true;
else
for (int index = 0; index < size; index++)
if (o.equals(elementData[index]))
fastRemove(index);
return true;
return false;
private void fastRemove(int index)
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
elementData[--size] = null;
indexOf操作
首先判断传进来的值是否为null,如果是null,那么则判断CustomArrayList
中是否夹杂着null元素,如果是的话,返回该元素的下标;如果并没有夹杂null元素,则返回-1
。
如果传进来的对象值不为null,那么遍历一遍CustomArrayList
,将找到的元素值的下标返回便可。
public int indexOf(Object o)
if (o == null)
for (int i = 0; i < size; i++)
if (elementData[i] == null)
return i;
else
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
return -1;
验证
public void getAll ()
for (int i = 0; i < size; i++)
System.out.println(elementData[i]);
getAll
方法主要是为了打印出目前数组中所有元素进行验证使用
public static void main(String[] args)
CustomArrayList arrayList = new CustomArrayList(5);
arrayList.add(0);
arrayList.add(1);
arrayList.add(8);
arrayList.add(9);
arrayList.getAll();
arrayList.remove(1);
Boolean flag = arrayList.remove(Integer.valueOf(8));
System.out.println(flag);
arrayList.getAll();
int index = arrayList.indexOf(null);
System.out.println(index);
以上是关于ArrayList的简单实现的主要内容,如果未能解决你的问题,请参考以下文章
Java数据结构list集合ArrayList集合LinkedList集合Vector集合