数组实现
父类:AbstractList
接口:List,RandomAccess,Cloneable,Serializable
字段:
//默认容量
private static final int DEFAULT_CAPACITY = 10;
//空的数组,构造函数参数为0和trim中使用,构造参数给0的人绝对会被打死,每放一个元素,就要重新copy一次
private static final Object[] EMPTY_ELEMENTDATA = {};
//实际保存数组,transient,这个字段不用写入流
transient Object[] elementData
//实际元素数目
private int size;
public ArrayList(int initialCapacity)
{
if (initialCapacity > 0)
{
this.elementData = new Object[initialCapacity];
}
else if (initialCapacity == 0)
{
//注意初始容量为0时给的对象,EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
}
else
{
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
public ArrayList()
{
//默认构造函数
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c)
{
//转入的集合转换为数组
elementData = c.toArray();
//改变自己的size
if ((size = elementData.length) != 0)
{
//这里有个坑,可能不能正确的返回Object[] Class对象,不能的话复制
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else
{
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
//截断,在原数组上移动
public void trimToSize()
{
modCount++;
if (size < elementData.length)
{
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
//比较关心的几个方法,存放,取出,查找
//查找,运行时间上界O(n),从这里也可用看出是允许放null
public int indexOf(Object o)
{
if (o == null)
{
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else
{
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
//反向查找
public int lastIndexOf(Object o)
{
if (o == null)
{
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else
{
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
//返回index位置的元素
E elementData(int index)
{
return (E) elementData[index];
}
//获取对应位置元素,O(1)
public E get(int index)
{
//检查size,并没有判断小于0
rangeCheck(index);
return elementData(index);
}
//将元素放在对应位置,index<size,list当成数组使用,注意,这样的代码会报错
//List<String> list = new ArrayList<>(100);
// list.set(10, "123");
//根据构造函数可以知道,已经开辟了100长度的数组,但是就是不让你用
public E set(int index, E element)
{
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
private void grow(int minCapacity)
{
// overflow-conscious code
int oldCapacity = elementData.length;
//原来的1.5备长度
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
elementData = Arrays.copyOf(elementData, newCapacity);
}
private void ensureExplicitCapacity(int minCapacity)
{
modCount++;
// overflow-conscious code
//1-0,进入if,进行内存复制,开辟新的数组
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void ensureCapacityInternal(int minCapacity)
{
//构造函数给0,这里是false
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
{
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//ensureExplicitCapacity(1);
ensureExplicitCapacity(minCapacity);
}
//增加一个元素
public boolean add(E e)
{
//为什么构造函数给0会被打死,看下面这个函数,一来就要新数组,新的数组长度也只有1
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//元素放到index位置,0<=index<size
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++;
}
//移除
public E remove(int index)
{
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
//内存复制
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
//O(n)的移除,注意在fastRemove方法里面也会出现内存复制
public boolean remove(Object o)
{
if (o == null)
{
for (int index = 0; index < size; index++)
if (elementData[index] == null)
{
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
//为什么elementData不用置null,方便重用
public void clear()
{
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
//浅克隆
public Object clone()
{
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
//返回副本
public Object[] toArray()
{
return Arrays.copyOf(elementData, size);
}
结尾附上一个内存分布的代码,有指针真好
int main(int argc, char* argv[])
{
//int ba[4];
int a[] = { 1, 2, 3, 4 };
int c = 5;
int d = 6;
int dd = 7;
cout << a << endl;
cout << a[-1] << endl;
cout << a-1 << endl;
cout<<&dd<<endl;
cout << &d << endl;
cout << &c << endl;
//memcpy(ba, a, sizeof(int) * 4);
//cout << ba[0] << endl;
//cout << ba[1] << endl;
return 0;
}