面试官Q1:能够手写一个ArrayList的简略实现吗?

咱们都晓得ArrayList是基于数组实现,如果让你实现JDK源码ArrayList中add()、remove()、get()办法,你晓得如何实现吗?这一节,咱们不看源码,咱们想想如何简略的实现ArrayList几个根本办法?

确定数据结构

咱们晓得,ArrayList中无论什么数据都能放,是不是意味着它是一个Object类型,既然是数组,那么是不是Object[]数组类型的?所以咱们定义的数据结构如下:

private Object[] elementData;  private int size;

设置自定义的MyArrayList的长度为10

public MyArrayList(){         this(10);     }      public MyArrayList(int initialCapacity){         if(initialCapacity<0){            try {                 throw new Exception();             } catch (Exception e) {                e.printStackTrace();            }        }        elementData = new Object[initialCapacity];    }

有了存放数据的地位,接下来,咱们想想如何将数据放入数组?

增加数据

public void add(Object obj){        elementData[size++]=obj;}

每增加一个元素,size就会自增1,咱们定义的数组长度为10,当咱们增加到11个元素的时候,显然没有中央寄存新增加的数据,这个时候咱们须要对数组进行扩容解决

对下面代码做如下批改:

 public void add(Object obj){         if(size==elementData.length){            //创立一个新的数组,并且这个数组的长度是原数组长度的2倍             Object[] newArray = new Object[size*2];            //应用底层拷贝,将原数组的内容拷贝到新数组             System.arraycopy(elementData, 0, newArray, 0, elementData.length);            //并将新数组赋值给原数组的援用             elementData = newArray;         }        //新来的元素,间接赋值        elementData[size++]=obj;}

用一张图来示意就是这样的:

查问数据

接着咱们看一下删除的操作。ArrayList反对两种删除形式:

  • 依照下标删除
  • 依照元素删除,这会删除ArrayList中与指定要删除的元素匹配的第一个元素

对于ArrayList来说,这两种删除的办法差不多,都是调用的上面一段代码:

 public void remove(int index){         //删除指定地位的对象         //a b d e         int numMoved = size - index - 1;         if (numMoved > 0){             System.arraycopy(elementData, index+1, elementData, index,                     numMoved);         }         elementData[--size] = null; // Let gc do its work}

其实做的事件就是两件:

  • 把指定元素前面地位的所有元素,利用System.arraycopy办法整体向前挪动一个地位
  • 最初一个地位的元素指定为null,这样让gc能够去回收它

用图示意是这样的:

指定地位增加数据

把从指定地位开始的所有元素利用System,arraycopy办法做一个整体的复制,向后挪动一个地位(当然先要用ensureCapacity办法进行判断,加了一个元素之后数组会不会不够大),而后指定地位的元素设置为须要插入的元素,实现了一次插入的操作。

public void add(int index,Object obj){        ensureCapacity();  //数组扩容        System.arraycopy(elementData, index, elementData, index + 1,                 size - index);        elementData[index] = obj;        size++;}

用图示意这个过程是这样的:

总结一下

从下面的几个过程总结一下ArrayList的特点:

  • ArrayList底层以数组实现,是一种随机拜访模式,通过下标索引定位数据,所以查找十分快
  • ArrayList在程序增加一个元素的时候十分不便,只是往数组外面增加了一个元素而已(这里指的开端增加数据)
  • 当删除元素的时候,波及到一次元素复制移位,如果要复制的元素很多,那么就会比拟消耗性能
  • 当插入元素的时候,波及到一次元素复制移位,如果要复制的元素很多,那么就会比拟消耗性能

因而,ArrayList比拟适宜程序增加、随机拜访的场景。

写在最初

欢送大家关注我的公众号【惊涛骇浪如码】,海量Java相干文章,学习材料都会在外面更新,整顿的材料也会放在外面。

感觉写的还不错的就点个赞,加个关注呗!点关注,不迷路,继续更新!!!