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中的ArrayList末尾附加元素?

如何在Java中的ArrayList末尾追加元素?

Java数据结构list集合ArrayList集合LinkedList集合Vector集合

Java数据结构list集合ArrayList集合LinkedList集合Vector集合

数据结构ArrayList原理及实现学习总结

Java集合框架 List接口实现类--ArrayList使用 & 删除小明