ArrayList
-
面试常问问题1
- ArrayList与HashMap的扩容方式有什么不同?
答:ArrayList是以1.5倍的方式扩容,而HashMap是以2倍扩容的
- ArrayList与HashMap的扩容方式有什么不同?
-
下面就分析下ArrayList的扩容函数
transient Object[] elementData; //ArraylIst底层的数据结构-》数组,**字段类型为Object[]**
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//ArrayList的最大Size
private void grow(int minCapacity){
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//可以看到ArrayList的确是1.5倍方式扩容的
if (newCapacity - minCapacity < 0)//限制newCapacity的最小尺寸->发生场景oldCapacity的大小为0
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//限制newCapacity的最大尺寸
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//旧数组复制到新数组的方式
}
-
面试常问问题2
- ArrayList的扩容方式是深复制还是浅复制?
即该代码段:elementData = Arrays.copyOf(elementData, newCapacity);
答:ArrayList的扩容一定是浅复制,因为ArrayList中保存的是对象的引用
- ArrayList的扩容方式是深复制还是浅复制?
-
下面就分析下ArrayList的复制函数Arrays.copyOf
elementData = Arrays.copyOf(elementData, newCapacity);
@SuppressWarnings("unchecked")
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass()); //orginal.getClass()获得original的Class对象;即T[]的对象信息
}
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
上述代码有两个点
- ((Object)newType == (Object)Object[].class)
解释:若newType的类型就是Object[]那么就可以直接进行new Object[newLength];否则,根据newType.getComponet()获得T[]中的T类型,并进行内存分配 - System.arraycopy,为将旧数组中的引用对象添加到新数组中。
-
面试常问问题3
ArrayList中可不可以添加null对象
答:可以的 -
面试常问问题4
ArrayList中插入、删除、查找、添加方法的时间复杂度
答:get/set/add方法的实际复杂度为O(1),而remove/insert/find的时间复杂度为O(n)