java中arraylist面试题_JAVA面试题 手写ArrayList的实现,在笔试中过关斩将?

面试官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;

}

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

2a8de61b1fb1f06d5b68e2d3b05e7e76.png

查询数据

public Object get(int index){

return elementData[index];

}

删除数据

接着我们看一下删除的操作。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可以去回收它

用图表示是这样的:

f5e9dd533c175f249c93eb97b802f49c.png

指定位置添加数据

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

public void add(int index,Object obj){

ensureCapacity(); //数组扩容

System.arraycopy(elementData, index, elementData, index + 1,

size - index);

elementData[index] = obj;

size++;

}

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

a0647a135320aebc7f8b0db18a54f7d1.png

总结一下

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

ArrayList底层以数组实现,是一种随机访问模式,通过下标索引定位数据,所以查找非常快

ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已(这里指的末尾添加数据)

当删除元素的时候,涉及到一次元素复制移位,如果要复制的元素很多,那么就会比较耗费性能

当插入元素的时候,涉及到一次元素复制移位,如果要复制的元素很多,那么就会比较耗费性能

因此,ArrayList比较适合顺序添加、随机访问的场景。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值