手写ArrayList简单实现其主要功能

package test;

import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * @author wcy
 *手写ArrayList(泛型)
 *要求:
 *add()
 *remove()
 *get()
 *set()
 *size()
 *iterator()
 *contain()
 *clear()
 */

public class ArrayListTest<T> {
    //默认容量为10
    private static final  int DEFAULT_CAPACITY = 10;

    /**
     * 用elementData数组存储书库,ArrayList的容量就是该数组的长度
     */
    Object[] elementData ;

    /**
     * 一个空数组
     * 用户使用有参构造函数指定长度为0时返回该数组
     */
    private static final Object[] EMPTY_ELEMRNTDATA = {};

    /**
     * 一个空的数组实例
     * 当用户构造空的ArrayList时(调用无参构造函数),返回该数组。
     * 注意和EMPTY_ELEMRNTDATA的区别
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_elementData = {};

    //ArrayList实际存储数量
    private int size;

    /**
     * 无参构造函数
     * 创建一个空的ArrayList,此时其内数组缓冲区 elementData = {},长度为0
     * 当元素第一次被加入时,扩容至默认容量10
     */
    public ArrayListTest() {
        this.elementData = DEFAULTCAPACITY_EMPTY_elementData;
    }

    /**
     * 有参构造函数(参数为数字(初始值))
     * @param initialCapacity  设置的初始容量
     * @throws IllegalArgumentException 若初始值小于0,抛出
     */
    public ArrayListTest(int initialCapacity) {
        if(initialCapacity>0) {
            this.elementData = new Object[initialCapacity];
        }else if(initialCapacity == 0) {
            this.elementData = EMPTY_ELEMRNTDATA;
        }else{
            throw new IllegalArgumentException("错误初始值,初始值必须大于1");
        }
    }

    /**
     * 有参构造函数(参数为集合)
     * @param c 要放入ArrayList中的集合,其中的元素会全部添加到新建的ArrayList实例中
     */
    public ArrayListTest(Collection<? extends T> c) {
        //将集合转换为Object数组
        elementData = c.toArray();
        //吧转换后的数组的长度赋值给当前ArrayList的size,并判断是否为0
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            // 这句话意思是:c.toArray 可能不会返回 Object[],可以查看 java 官方编号为 6260652 的 bug
            if (elementData.getClass() != Object[].class)
                // 若 c.toArray() 返回的数组类型不是 Object[],则利用 Arrays.copyOf(); 来构造一个大小为 size 的 Object[] 数组
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // 替换空数组
            this.elementData = EMPTY_ELEMRNTDATA;
        }
    }

    /**
     * 数组缓冲区最大存储容量
     * 为什么减去8?-->一些VM会在一个数组中存储某些数据
     */
    private static final  int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 扩容方法
     * 确保ArrayList至少能存储minCapacity个元素
     * 扩容公式:新容量 = 旧容量 + (旧容量>>1);即相当于扩充为当前的1.5倍
     * @param minCapacity 指定的最小容量
     */
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >>1);
        if(newCapacity < minCapacity) {
            newCapacity = minCapacity;
        }
        if(newCapacity>MAX_ARRAY_SIZE) {
            newCapacity = hugeCapacity(minCapacity);
        }
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    /**
     * 大容量分配,最大分配Integer.MAX_VALUE
     * @param minCapacity
     */
    private static int hugeCapacity(int minCapacity) {
        if(minCapacity <0) {
            throw new OutOfMemoryError();
        }
        return (minCapacity > MAX_ARRAY_SIZE)?Integer.MAX_VALUE:MAX_ARRAY_SIZE;
    }
    /**
     * 保证ArrayList的容量足够add()函数添加元素
     * @param minCapacity
     */
    private void ensureCapacityInternal(int minCapacity) {
        if(elementData == DEFAULTCAPACITY_EMPTY_elementData) {
            minCapacity = Math.max(minCapacity, DEFAULT_CAPACITY);
        }
        if(minCapacity > elementData.length) {
            grow(minCapacity);
        }
    }

    /**
     * size() 发牛ArrayList实际存储的元素数量
     */
    public int size() {
        return size;
    }

    /**
     * 判断ArrayList是否为空
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 判断ArrayList是否半酣某个元素
     */
    public boolean contains(Object o) {
        return indexOf(o)>=0;
    }

    /**
     * indexOf(Object o)
     * @return 存在? 最低索引值:-1
     */
    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;
    }

    /**
     * get()函数
     * @param index
     * @return 返回指定位置上的元素(从零开始)
     */
    public T get (int index) {
        rangeCheck(index);
        return (T) elementData[index];
    }

    /**
     * set(int index,T element) 函数,设置elementData[index]的值为element
     * @param index
     * @param element
     * @return 先前位于指定位置的元素
     */
    public T set (int index,T element) {
        rangeCheck(index);
        T oldValue = (T) elementData[index];
        elementData[index] = element;
        return oldValue;
    }

    /**
     * 检查索引是否越界,若越界则抛出异常
     * IndexOutOfBoundsException(String s)方法打印字符串
     */
    public void rangeCheck(int index) {
        if(index>=size) {
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    }
    /**
     * 
     * @param index
     * @return 返回一个字符串,表明所求索引和实际大小
     */
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

    /**
     * 添加某个元素到arraylist的末尾
     * @param e
     * @return
     */
    public boolean add(T e) {
        ensureCapacityInternal(size+1);
        elementData[size++] = e;
        return true;

    }

    public void add (int index,T element) {
        rangeCheck(index);
        //保证容量足够大
        ensureCapacityInternal(size+1);
        //将index位置及其之后所有元素向后移动一位
        //arraycopy函数,第一个参数为要复制的数组,第二个为开始复制的下标,第三个为复制到哪个数组,第四个为复制到数组的什么位置开始,最后一个参数是复制数组的长度
        System.arraycopy(elementData, index, elementData, index+1, size-index);
        //在空出来的位置上添加需要添加的值
        elementData[index] = element;
        //size属性+1
        size++;
    }

    /**
     * 按下表索引移除元素
     * @param index
     */
    public void remove (int index) {
        rangeCheck(index);
        int numMoved = size -index -1;
        if(numMoved > 0) {
            System.arraycopy(elementData, index+1, elementData, index, numMoved);
        }
        //将最后一个元素置空
        elementData[--size] = null;
    }

    /**
     * 按照数组中第一个o元素
     * @param o
     * @return
     */
    public boolean remove (Object o) {
        if(o == null) {
            for(int i = 0;i<size;i++) {
                if(elementData[i] == null) {
                    remove(i);
                    return true;
                }
            }
        }else {
            for(int i = 0;i<size;i++) {
                if(o.equals(elementData[i])) {
                    remove(i);
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 清空ArrayList中的所有元素
     */
    public void clear() {
        for(int i = 0;i<size;i++) {
            elementData[i] = null;
        }
        size = 0;
    }


    public Iterator<T> iterator(){
        return new Itr();
    }

    private class Itr implements Iterator<T>{

        int cursor;       // 光标,默认为0,为下个元素的索引
        int lastRet = -1; // 最后一个元素的索引 

        /**
         * 查询是否有下一个元素
         */
        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            return cursor!=size;
        }
        /**
         * 返回下一个元素
         */
        @Override
        public T next() {
            // TODO Auto-generated method stub
            int i = cursor;
            if(i>=size) {
                throw new NoSuchElementException();
            }
            if(i>= elementData.length) {
                throw new ConcurrentModificationException();
            }
            cursor = i+1;
            //给lastRet赋值
            return (T) elementData[lastRet = i];
        }

        //需要和next配合使用
        public void remove() {
            if(lastRet<0) {
                throw new IllegalStateException();
            }
            try {
                //移除最后一个元素
                ArrayListTest.this.remove(lastRet);
                //cursor比lastRet大1,所以指针往前移动一位
                cursor = lastRet;
                //将lastRet重新设为-1
                lastRet = -1;
            }catch (IndexOutOfBoundsException  e) {
                throw new ConcurrentModificationException();
            }
        }

    }






    //测试
    public static void main(String[] args) {
        ArrayListTest<Integer> a = new ArrayListTest<>();
        a.add(1);
        a.add(2);
        a.add(3);
//        a.add("测试");
//        System.out.println("size"+"="+a.size);
//        for(int i = 0;i<a.size;i++) {
//            System.out.println(a.get(i));
//        }
//        System.out.println("--------");
//        a.remove(0);
//        System.out.println("size"+"="+a.size);
//        for(int i = 0;i<a.size;i++) {
//            System.out.println(a.get(i));
//        }
//        System.out.println("--------");
//        a.set(0, 1);
//        for(int i = 0;i<a.size;i++) {i
//            System.out.println(a.get(i));
//        }
         Iterator<Integer> itr = a.iterator();
        while(itr.hasNext()) {
            System.out.println(itr.next());
        }


    }

}

实现栈

package test;
/**
 * 用自己写的ArrayList实现栈
 * @author wcy
 *pop()
 *push (Object o)
 *isEmpty()
 *getStackSize()
 */
public class StackTest {
    private ArrayListTest list= new ArrayListTest<>() ;
    //压栈
    public void push (Object o) {
        System.out.println("进栈元素为:"+o);
        list.add(o);
    }
    //检查栈是否为空
    public boolean isEmpty() {
        return list.isEmpty();
    }
    //出栈
    public void pop() {
        Object obj = null;
        if(list.isEmpty()) {
            return;
        }else {
            obj = list.get(list.size()-1);
            System.out.println("出栈的元素为:"+obj);
            list.remove(obj);
        }

    }
    //返回栈中元素数量
    public int getStackSize() {
        return list.size();
    }

    public static void main(String[] args) {
        StackTest stack = new StackTest();
        stack.push(1);
        stack.push("df");
        stack.push(3);
        System.out.println(stack.getStackSize());
        stack.pop();
        stack.pop();
    }
}