ArrayList

一、ArrayList
内部是由一个Object[] 数组实现
private transient Object[] elementData ;

private int size ;
1、ArrayList里面元素的个数,这里要注意一下,size是按照调用add、remove方法的次数进行自增或者自减的,所以add了一个null进入ArrayList,size也会加1 
2、ArrayList不是线程安全的,所以在多线程的环境下使用ArrayList需要注意ArrayList类型变量的线程同步问题。当然,有一种方式可以创建一个线程安全的ArrayList: 
List list = Collections.synchronizedList(new ArrayList(…)); 
3、ArrayList 所有操作都是围绕数组进行的,Arrays.copyOf 方法
4、为什么ArrayList的elementData是用transient修饰的?
public class ArrayList<E> extends AbstractList<E>
implements List<E> , RandomAccess, Cloneable, java.io.Serializable
看到ArrayList实现了Serializable接口,这意味着ArrayList是可以被序列化的,用transient修饰elementData意味着我不希望elementData数组被序列化。这是为什么?因为序列化ArrayList的时候,ArrayList里面的elementData未必是满的,比方说elementData有10的大小,但是我只用了其中的3个,那么是否有必要序列化整个elementData呢?显然没有这个必要,因此ArrayList中重写了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 array length s.writeInt(elementData.length);
// 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();
}
}
每次序列化的时候调用这个方法,先调用defaultWriteObject()方法序列化ArrayList中的非transient元素,elementData不去序列化它,然后遍历elementData,只序列化那些有的元素,这样:
1、加快了序列化的速度
2、减小了序列化之后的文件大小
不失为一种聪明的做法,如果以后开发过程中有遇到这种情况,也是值得学习、借鉴的一种思路。
添加、删除元素:
 public boolean add(E e) {
      ensureCapacityInternal(size + 1);  // Increments modCount!!
      elementData[size++] = e;
      return true;
 }

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

//添加元素核心代码
  private void ensureCapacityInternal ( int minCapacity ) {
        if ( elementData == 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 );
    }
    /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static final int MAX_ARRAY_SIZE = Integer. MAX_VALUE - 8;
    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    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 ;
    }  

ArrayList的优点如下:
1、ArrayList底层以数组实现,是一种 随机访问 模式,再加上它实现了RandomAccess接口,因此查找也就是get的时候非常快
2、ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已
不过ArrayList的缺点也十分明显:
1、删除元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能
2、插入元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能
因此, ArrayList比较适合顺序添加、随机访问的场景

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值