ArrayList
ArrayList
是基于数组(Object[ ])实现的,所以支持快速随机访问。
RandomAccess:标识该类支持快速随机访问
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
数组默认大小:10
private static final int DEFAULT_CAPACITY = 10;
扩容机制
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
添加元素时确认容量大小: ensureCapacityInternal()
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);
}
容量不够,扩容: grow()
扩容后的容量:旧容量的1.5倍:oldCapacity + (oldCapacity >> 1)
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //扩容为原来的1.5倍
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); // 扩容操作要调用Arrays.copyOf() 把原数组复制到新数组中,但代价高效率低
//一般先指定ArrayList的容量大小,减少扩容操作次数。
}
删除操作
调用System.arraycopy() : 将index+1后的元素复制从index上开始的位置
操作时间复杂度O(N) 代价高
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;
}
序列化
ArrayList基于数组实现,具有动态扩容机制,保存的元素不一定都会被使用,没必要全部进行序列化。
不序列化:保存元素的数组 elementData 使用 transient 修饰(transient:默认不会被序列化。)
transient Object[] elementData;
// non-private to simplify nested class access
控制序列化数组中的元素内容的方法:writeObject() 、 readObject()
//readObject()
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
//writeObject()
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
序列化操作:使用 ObjectOutputStream 的 writeObject() 将对象转换为字节流并输出
writeObject() 方法在传入的对象存在 writeObject() 的时候会去反射调用该对象的 writeObject() 来实现序列化。
User user = new User();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("heyuFile"));
oos.writeObject(user);
反序列化操作:ObjectInputStream 的 readObject() 方法
File file = new File("heyuFile");
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
User user =(User)objectInputStream.readObject();
Fail-Fast 快速失败:
在做系统设计的时候先考虑异常情况,一旦发生异常,直接停止并上报。
在系统设计中,快速失效系统一种可以立即报告任何可能表明故障的情况的系统。快速失效系统通常设计用于停止正常操作,而不是试图继续可能存在缺陷的过程。这种设计通常会在操作中的多个点检查系统的状态,因此可以及早检测到任何故障。快速失败模块的职责是检测错误,然后让系统的下一个最高级别处理错误。
ConcurrentModificationException异常(CMException):
当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常
发生CMException,优先考虑fail-fast有关的情况,实际上这里并没有真的发生并发,只是Iterator使用了fail-fast的保护机制,只要他发现有某一次修改是未经过自己进行的,那么就会抛出异常。

浙公网安备 33010602011771号