//简单了解ArrayList
//extends abstractList implements List<>,RandomAccess, Cloneable, java.io.Serializable
//由于实现了List<E> 其实是间接实现了Collection<E>,Iterable<E>这儿可以看出java如何实现多继承。
//如果说简单的使用,那么看看ApI 可以。但是了解"背后的真相"还是的看JDK源码。
//1、ArrayList 是怎么样能够自动扩容的呢?
/*public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
* 如上面代码所示,当我们add(new Object())时,其实就会调用ensureCapacityInternal(size+1);来确保此时的ArrayList的容量大小。(这里用了copyOf()我们应该知道
* 这里扩容的本质其实是复制内容到新对象数组中,只不过产生这个新数组的时候容量被指定为多大多大,多出来的填充为null)如果ArrayList是默认的大小10,那么新增加一个元素对象后大
* 于10,那么就会扩容到5+10。如果小于10,那么还是默认大小。
*2、ArrayList removeRange(fromIndex,toIndex) 怎么实现。
* protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
这里用了系统类的arraycopy方法。(Object src,int srcPos,Object dest,int destPos,int length)所以很容易得出(elementData,toIndex,elementData,fromIndex,numMoved)
* 3、removeAll(Collection<?> c );retainAll(Collection<?> c);
* public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
* public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
*在源码里我们都遇到了Arrays.copyOf(),system.arraycopy();有什么区别呢?arraycopy()可以对俩个数组进行各种类型的合并操作,copyOf()其实还是在内部新建一个数组,
*然后调用system.arraycopy()进行复制。但是数组是在建的时候就定义好大小。
了解 ArrayList 源码(一)
最新推荐文章于 2024-05-03 12:16:16 发布