关于ArrayList的5道面试题

    |     2017年3月2日   |   面试   |     0 条评论   |    856

以面试官视角看过不少 Java 面试后,下面 5 道 ArrayList 题最容易让初中级同学含糊过去。答清楚,分数会好看很多。

2280210133826


一、ArrayList 的大小如何自动增加?

这是最有技巧的一题,多数人答不上细节。往 ArrayList 里 add 时,Java 会检查现有数组够不够装新对象。不够就新建更长的数组,用 Arrays.copyOf 把旧数据拷过去,再让 elementData 指向新数组。

代码摘自 GrepCode.com 中的 Java ArrayList Code(OpenJDK 6):

//ArrayList Add方法:
public boolean add(E e){
    ensureCapacity(size+1); //Increment modCount!!
    elementData[size++] = e;
    return true;
}

//ensureCapacity方法:处理ArrayList的大小
public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
    if (newCapacity < minCapacity)
        newCapacity = minCapacity;
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

注意三件事:新建数组;旧对象拷到新数组;现有引用改指向新数组。扩容公式在 JDK 6 是 (oldCapacity * 3)/2 + 1。


二、什么时候用 ArrayList,什么时候用 LinkedList?

访问比插入/删除更频繁时用 ArrayList;在某个下标频繁插入删除、或几乎不随机访问时用 LinkedList。

原因:ArrayList 按下标访问最坏是 O(1),LinkedList 可能是 O(n)。ArrayList 增删通常要 System.arraycopy,很吃资源,所以频繁插入删除时 LinkedList 更好。

场景 更合适 原因
按下标读、遍历多 ArrayList 数组随机访问 O(1)
中间频繁增删 LinkedList 改指针,避免整段 arraycopy
几乎只当队列头尾操作 LinkedList / 队列实现 不需要按下标跳

三、把 ArrayList 传入或返回时,何时有安全隐患?

数组(同样适用于可变的 ArrayList 引用)若未经拷贝就直接赋给成员变量,调用方之后改原始数据,方法内部看到的那份也会变。下面是违规与修复。

ArrayList 被直接赋给成员变量——安全隐患:

修复这个安全隐患(先拷贝再保存):


四、如何把某个 ArrayList 复制到另一个?

几种做法:

  1. 使用 clone(),例如 ArrayList newArray = oldArray.clone();
  2. 使用 ArrayList 构造方法,例如 ArrayList myObject = new ArrayList(myTempObject);
  3. 使用 Collection 的 copy 方法。

注意 1 和 2 是浅拷贝(shallow copy)。


五、按下标增删对象时发生了什么?很慢吗?

增删要调用 System.arraycopy,效率低。需要频繁插入删除时换 LinkedList 等集合。

在某个索引 i 处添加元素:

删除某个索引 i 处的元素:

原文链接:vitalflux 翻译:ImportNew.com – kobekillerjun
译文链接:http://www.importnew.com/9928.html

一句话总结:ArrayList 靠数组扩容(JDK6 约 1.5 倍)和 arraycopy 搬家;随机访问快、中间增删慢,对外暴露前要拷贝,clone/构造都是浅拷贝。

转载请注明来源:关于ArrayList的5道面试题
本文链接地址:https://ai.zhousir.top/?p=2273
回复 取消