实现一个基于数组的ArrayList

package com.hu;

import java.util.*;

public class MyArrayList<E> implements MyList<E> {

    private int size;
    private Object[] elementData;
    private static final int DEFAULT_CAPACITY = 10;
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    private int modCount;


    //无参构造方法
    public MyArrayList (){
        elementData=new Object[DEFAULT_CAPACITY];
    }
    //1参构造方法,指定初始容量
    public MyArrayList (int minCapacity){
        elementData=new Object[minCapacity];
    }



    //增加元素
    @Override
    public boolean add(E e) {

        add(size,e);
        return true;
    }

    //在指定索引位置增加元素
    @Override
    public void add(int index, E element) {
        //检查index是否越界
        rangeCheckForAdd(index);

        int newCapacity=size+1;
        //是否需要扩容
        if(newCapacity>elementData.length){
            //扩容的计算方法
            newCapacity=capacityCaculate(newCapacity);
            }

        //扩容
        grow(newCapacity);

        //为新加入的元素腾出位置
        for(int i=size-1;i>=index;i--){
            elementData[i+1]=elementData[i];
        }
        //放置元素
        elementData[index]=element;

        size++;

        //集合发生结构性变化
        modCount++;
    }

    //扩容的计算方法
    private int capacityCaculate(int minCapacity) {
        int newcapacity=minCapacity+minCapacity>>1;
        if(newcapacity<0||newcapacity>Integer.MAX_VALUE){
            newcapacity=MAX_ARRAY_SIZE;
        }

        //如果minCapacity值比较大,它扩容1.5倍之后超过了Integer最大值,但是它又比我们设置的默认最大值MAX_ARRAY_SIZE大
        //此时我们直接将minCapacity设为集合容量大小
        return (newcapacity>minCapacity)?newcapacity:minCapacity;

    }

    //扩容
    private void grow(int newCapacity){
        elementData= Arrays.copyOf(elementData,newCapacity);
    }

    //检查索引位置合法性
    private void rangeCheckForAdd(int index) {
        if(index<0||index>size){
            throw new IndexOutOfBoundsException("size=:"+size);
        }
    }


    //清楚集合所有元素
    @Override
    public void clear() {
        for(int i=0;i<size;i++){
            elementData[i]=null;
        }
        size=0;
        modCount++;
    }

    //判断元素是否包含
    @Override
    public boolean contains(Object o) {
        //如果o是null的话,要单独判断,因为equals不能比较null
        if(o==null){
            for (int i=0;i<size;i++){
                if(elementData[i]==null){
                    return true;
                }
            }
        }
        for(int i=0;i<size;i++){
            if(elementData[i].equals(o)){
                return true;
            }
        }
        return false;
    }


    //获得指定位置元素值
    @Override
    public E get(int index) {
        //判断索引合法性
        rangeCheckForGet(index);
        return (E) elementData[index];
    }


    /**
     *
     * @param index 0-size-1
     */
    private void rangeCheckForGet(int index) {
        if(index<0||index>size-1){
            throw new IndexOutOfBoundsException("index="+index);
        }
    }


    /**
     * 获得指定元素首次出现的位置
     * @param o
     * @return 找不带指定元素返回-1
     */
    @Override
    public int indexOf(Object o) {
        if(o==null){
            for(int i=0;i<size;i++){
                if(elementData[i]==null){
                    return i;
                }
            }
        }
        for(int i=0;i<size;i++){
            if(elementData[i].equals(o)){
                return i;
            }
        }
        //找不到指定元素返回-1
        return -1;
    }



    /**
     * 获得指定元素最后出现的位置
     * @param o
     * @return 找不带指定元素返回-1
     */
    @Override
    public int lastIndexOf(Object o) {
        if(o==null){
            for(int i=size-1;i>=0;i--){
                if(elementData[i]==null){
                    return i;
                }
            }
        }
        for(int i=size-1;i>=0;i--){
            if(elementData[i].equals(o)){
                return i;
            }
        }
        //找不到指定元素返回-1
        return -1;
    }

    //判断集合是否为空
    @Override
    public boolean isEmpty() {
        return size==0;
    }


    //删除指定索引位置的元素
    @Override
    public E remove(int index) {
        //检查索引合法性
        rangeCheckForGet(index);
        E element=(E) elementData[index];
        for(int i=index+1;i<size;i++){
            elementData[i-1]=elementData[i];
        }
        size--;
        modCount++;
        return element;
    }


    //删除指定元素
    @Override
    public boolean remove(Object o) {

        if(o==null){
            for(int i=0;i<size;i++){
                if(elementData[i]==null){
                    remove(i);
                    return true;
                }
            }
        }

        for(int i=0;i<size;i++){
            if(elementData[i].equals(o)){
                remove(i);
                return true;
            }
        }
        return false;
    }


    //将指定索引位置的元素更改为指定的元素
    @Override
    public E set(int index, E element) {
        //检查索引合法性检查
        rangeCheckForGet(index);
        E e = (E)elementData[index];
        elementData[index]=element;
        return e;
    }

    @Override
    public int size() {
        return size;
    }



    @Override
    public ListIterator<E> listIterator() {
        return new MyListIterator();
    }

    @Override
    public ListIterator<E> listIterator(int index) {
        return new MyListIterator(index);
    }


    private  class MyListIterator implements  ListIterator<E>{
        //初始游标索引为0
        int cursor;
        //lastRet是为remove()、add()和set()方法设计的
        int lastRet=-1;
        //exceptModCount用于监测迭代器外部是否更改了集合结构
        int exceptModCount=modCount;

        //无参构造方法
        public MyListIterator() {
        }
        //一参构造方法,指定游标起始位置
        public MyListIterator(int index) {
            cursor=index;
        }

        //hasNext()判断cursor后是否还有元素
        @Override
        public boolean hasNext() { return cursor<size; }

        //next()返回cursor指向的那个元素
        @Override
        public E next() {
            //检查是否有并发修改异常
            checkConcurrentModficationException();
            if(hasNext()){
                E e = (E)elementData[cursor];
                lastRet=cursor;
                cursor++;
                return e;
            }else {
                //游标已经走到了最后
                throw new NoSuchElementException("cursor="+cursor);
            }
        }

        //检查是否有并发修改异常
        private void checkConcurrentModficationException() {
            if(exceptModCount!=modCount){
                throw new ConcurrentModificationException("集合结构发生变化");
            }
        }

        //hasPrevious()判断cursor前是否还有元素
        @Override
        public boolean hasPrevious() {
            return cursor>0;
        }

        //
        @Override
        public E previous() {
            checkConcurrentModficationException();
            if(hasPrevious()){
                E e=(E) elementData[cursor-1];
                cursor--;
                lastRet=cursor;
                return e;
            }else {
                //游标已经走到了最前面
                throw new NoSuchElementException("cursor="+cursor);
            }
        }

        //nextIndex()返回cursor,下一次next()返回的元素的索引
        @Override
        public int nextIndex() {
            return cursor;
        }

        //previousIndex()返回cursor-1,下一次previous()返回的元素的索引
        @Override
        public int previousIndex() { return cursor-1; }



        @Override
        public void remove() {
            checkConcurrentModficationException();
            //lastRet如果小于0,说明还未调用next()或previous(),或者调用了next()和previous()之后又重新调用了迭代器的add()或set()方法,
            // 或者已经调用了remove()方法,导致lastRet,又重新置为-1
            if(lastRet<0){
                throw new IllegalStateException("lastRet="+lastRet);
            }
            //调用MyArrayList的remove(int index)删除元素
            MyArrayList.this.remove(lastRet);
            cursor=lastRet;
            lastRet=-1;
            //迭代器内部更改集合结构不应该造成并发修改异常
            exceptModCount=modCount;
        }

        @Override
        public void set(E e) {
            checkConcurrentModficationException();
            //lastRet如果小于0,说明还未调用next()或previous(),或者调用了next()和previous()之后又重新调用了迭代器的add()或remove()方法,
            // 或者已经调用了set()方法,导致lastRet,又重新置为-1
            if(lastRet<0){
                throw new IllegalStateException("lastRet="+lastRet);
            }
            elementData[lastRet]=e;
            lastRet=-1;
            //这里并未更改集合结构
            //exceptModCount=modCount;
        }

        @Override
        public void add(E e) {
            checkConcurrentModficationException();
            //lastRet如果小于0,说明还未调用next()或previous(),或者调用了next()和previous()之后又重新调用了迭代器的add()或remove()方法,
            // 或set()方法,导致lastRet,又重新置为-1
            if (lastRet<0){
                throw new IllegalStateException("lastRet="+lastRet);
            }
            //调用MyArrayList的add(int index,E e)添加元素
            MyArrayList.this.add(cursor,e);
            lastRet=-1;
            迭代器内部更改集合结构不应该造成并发修改异常
            exceptModCount=modCount;
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyArrayList<?> that = (MyArrayList<?>) o;
        return size == that.size &&
                modCount == that.modCount &&
                Arrays.equals(elementData, that.elementData);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(size, modCount);
        result = 31 * result + Arrays.hashCode(elementData);
        return result;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append("[");
        if (size>0){
            for (int i=0;i<size-1;i++){
                stringBuilder.append(elementData[i]+",");
            }
            stringBuilder.append(elementData[size-1]+"");
        }

        stringBuilder.append("]");
        return  stringBuilder.toString();
    }
}





package com.hu;

import java.util.ListIterator;

public class Test {
    public static void main(String[] args) {
       MyArrayList<String> list = new MyArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("b");
        list.add("c");
        list.add(1,"1");
        System.out.println("初始集合为:"+list);

     


   boolean contains = list.contains("1");
        System.out.println("是否包含元素1:"+contains);

        String s = list.get(3);
        System.out.println("索引为3的元素为:"+s);

        int b = list.indexOf("b");
        System.out.println("首次出现元素b的索引为:"+b);

        int b1 = list.lastIndexOf("b");
        System.out.println("最后出现元素b的索引为:"+b1);

        boolean empty = list.isEmpty();
        System.out.println("集合是否为空:"+empty);

        String remove = list.remove(3);
        System.out.println("删除索引为3的元素后,集合为:"+list);

        boolean b2 = list.remove("b");
        System.out.println("是否成功删除了集合中第一次出现的元素b:"+b2+"  "+"删除第一次出现的元素b后集合为:"+list);

        String a = list.set(1, "aa");
        System.out.println("将索引为1的元素更改为元素aa,被更改的元素是:"+a+"   "+"更改后集合为:"+list);

        list.clear();
        System.out.println("清除集合所有元素后,集合为:"+list+"   "+"此时集合size为"+list.size());





        System.out.println("------------------------------------------------------------------------------------------");
        System.out.println("-----------------------------------测试迭代器---------------------------------------------");
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        System.out.println("初始集合为:"+list);


        ListIterator<String> listIterator = list.listIterator(1);
        System.out.println("1.下面正向遍历从cursor等于1开始遍历,这可以测试迭代器的有参构造方法");
        for(;listIterator.hasNext();){
            System.out.print(listIterator.next()+" ");
        }
        System.out.println();
        System.out.println("下面逆向遍历从cursor等于size开始遍历");
        for(;listIterator.hasPrevious();){
            System.out.print(listIterator.previous()+" ");
        }
        System.out.println();

        System.out.println("2.测试nextIndex()和previousIndex(),此时cursor为0");
        System.out.println("nextIndex=:"+listIterator.nextIndex()+"    "+"previousIndex()=:"+listIterator.previousIndex());

        System.out.println("3.上面逆向遍历已经将cursor置为0,现在开始测试迭代器的remove()方法");
        String next = listIterator.next();
        listIterator.remove();
        System.out.println("remove()删除的next()返回的那个元素,也就是"+next+"   "+"删除后集合为:"+list);


        System.out.println("4.测试迭代器的add()方法,上面调用过remove(),此时lastRet已经置为-1,不能直接调用add()");
        String next1 = listIterator.next();
        listIterator.add("111");
        System.out.println("迭代器的add()方法在next()方法已经返回的那个元素后面加入元素111,已经返回的元素为:"+next1+"  "+"增加元素111后,集合为:"+list);

        System.out.println("5.测试迭代器的set()方法,同理,上面调用过remove()和add(),此时lastRet已经置为-1,不能直接调用set()");
        String next2 = listIterator.next();
        listIterator.set("222");
        System.out.println("迭代器的set()方法将next()方法已经返回的那个元素更改为元素222,已经返回的元素为:"+next2+"  "+"增加元素222后,集合为:"+list);


//        System.out.println("测试并发修改异常");
//        ListIterator<String> listIterator = list.listIterator();
//        String next = listIterator.next();
//        listIterator.add("111");
//        System.out.println(list);
//        listIterator.remove();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值