Java集合类-ArrayList分析

ArrayList的特点

非线程安全
支持序列化
可以动态扩容
线程安全的List Collections.synchronizedList、CopyOnWriteArrayList

成员变量

private static final int DEFAULT_CAPACITY = 10; // 初始大小
transient Object[] elementData;  // 存储元素的数组
private int size; //容器大小

基本方法

增 add

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
}
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);
}

 

删 remove

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;

  // 向前移动numMoved个元素,最后一个元素置为null
if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }

 

改 set

public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

 

查 get

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

 

 

ArrayList扩容原理

如果新加入元素后数组容量不够需要进行扩容,执行grow方法

默认扩容为之前的1.5倍,如果容量不够则直接扩充为加入当新元素后的大小 

然后利用Arrays.copyOf进行数组的复制

相关类和方法

Arrays.copyOf()

System.arraycopy()

public static native void arraycopy(

  Object src,
  int srcPos,
  Object dest,
  int destPos,
  int length

);

一些问题

ArrayList如何序列化?

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();
    }
}

序列化时JVM调用writeObject方法,只将数组size内的元素进行序列化,多余空间不进行序列化

参考

http://blog.csdn.net/ns_code/article/details/35568011

http://blog.csdn.net/qfycc92/article/details/45370011

 

posted @ 2017-10-11 00:02  【Java后端笔记】  阅读(244)  评论(0编辑  收藏  举报