有参构造:
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
这个看上去就没这么复杂了,初始化数组都给定了长度,不会出现无参构造那种想要一个长度10的数组却给了个长度为0的数组。
if分支对数组索引划分三个区间:
1.initialCapacity>0,将数组容量设为人为定义的值
2.initialCapacity==0,将数组容量设为默认值:10
3.initialCapacity<=,报非法数据异常,并提示输入的<0的数字。
有参add方法:
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
这个方法的意图就是插入一个元素到指定的所以位置。
1.rangeCheckForAdd()
我们先看add中的rangeCheckForAdd方法:
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
只要输入的所以位置比元素个数大或者索引小于0就抛一个Index越界异常。
可能有人会好奇为什么是index>size
问:假设当前有6个元素,那你输入一个7,这样可以插入成吗?
答:当然不可以
int a [] = new int[10];
int size=0;
a[size++]=99;
就用三行解释,a[0]=99,a[1]=0
有1个元素,不能插在a[2]的位置,中间的a[1]就浪费了。
有6个元素,不能插在a[7]的位置。
2.ensureCapacityInternal()
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
这个方法上篇帖子有解释:看看要不要扩容。
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
需要扩容就grow()进行扩容。
3.System.arraycopy()
//src 原数组
//src 原数组开始位置
//dest 目标数组
//destPos 目标数组开始位置
//length 要复制的长度
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
这个方法在final类System中,是一个java调用,不是接口。我们看上去类似一个抽象方法,它没有方法体,实则它有实体,只不过它的实体不再是java代码。
那就直接挖到我们能看懂的最底层,一部一部找下去,直到C语言库函数中的memmoe方法:
void *memmove(void *dest, const void *src, size_t count){
assert( (dest!=NULL)&&(src!=NULL) );
char *tmp_dest=(char*)dest;
char *tmp_src=(char*)src;
if( tmp_dest<tmp_src) {
// 如果没有重叠区域
while(count--)
*tmp_dest++=*tmp_src;
} else {
// 如果有重叠区域
tmp_dest+=count-1;
tmp_src+=count-1;
while(count--)
*--tmp_dest=*--tmp_src;
}
return dest;
}
函数功能:将字符串src中的前n个字节拷贝到dest中。
&spm=1001.2101.3001.5002&articleId=106516848&d=1&t=3&u=ceff909e7dbb47ba990c00ccb0b3ac6b)
781

被折叠的 条评论
为什么被折叠?



