zoukankan      html  css  js  c++  java
  • ArrayList源码分析

            ArrayList是java中最常使用的动态数组,其具体使用方式就不再介绍,本文只是从源码角度介绍它内部的序列化和扩容机制。ArrayList作为集合框架中的一员,它的继承关系如下所示:

    image

    public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess

            从它实现的接口来看,ArrayList支持clone,序列化,随机访问。在类中维持了两个成员变量:

    int size;
    
    transient Object[] array;

            其中size是ArrayList的长度,array是一个object类型的数组用于存储数据元素,元素本身也可以为null。等等,这里为什么事transient来修饰的呢?说好的序列化呢?

           原来,ArrayList并没有使用默认的序列化机制,而是实现了readObjectwriteObject 方法来完成序列化工作:

    private void writeObject(ObjectOutputStream stream) throws IOException {
            stream.defaultWriteObject();
            stream.writeInt(array.length);
            for (int i = 0; i < size; i++) {
                stream.writeObject(array[i]);
            }
        }
    
        private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
            stream.defaultReadObject();
            int cap = stream.readInt();
            if (cap < size) {
                throw new InvalidObjectException(
                        "Capacity: " + cap + " < size: " + size);
            }
            array = (cap == 0 ? EmptyArray.OBJECT : new Object[cap]);
            for (int i = 0; i < size; i++) {
                array[i] = stream.readObject();
            }
        }

            这种方法比默认的机制更为高效,它并未存储整个数组中的null,这样节省了很多空间。

            解释完序列化的疑问,我们来看一下它的动态增长机制,在add方法中:

    public boolean add(E object) {
            Object[] a = array;
            int s = size;
            if (s == a.length) {
                Object[] newArray = new Object[s +
                        (s < (MIN_CAPACITY_INCREMENT / 2) ?
                         MIN_CAPACITY_INCREMENT : s >> 1)];
                System.arraycopy(a, 0, newArray, 0, s);
                array = a = newArray;
            }
            a[s] = object;
            size = s + 1;
            modCount++;
            return true;
        }

            我们可以看到,当数组容量不足对数组扩容的时候,有一个判断:当前长度是否是最小增长长度(MIN_CAPACITY_INCREMENT  12)的1/2,如果小于则按最小增长长度进行扩容,否则扩容为当前容量的3/2.

            以上便是ArrayList源码学习中需要注意的两个疑问。

  • 相关阅读:
    【Vegas原创】解决System.Web.Extensions版本冲突方法
    【Vegas原创】GridView修改表头,并导出Excel(C#版)
    bdump,cdump,udump作用
    【Vegas原创】用正则表达式解决FCKEditor图片路径问题
    【Vegas改编】获取,更新web.config的值
    面向对象和面向过程的区别
    【Vegas原创】删除有内外键关系数据的方法
    提供css滤镜代码,变网页为黑白,为在地震中遇难的同胞哀悼
    【Vegas原创】将treeview父结点的链接改为折叠事件
    C#经典试题
  • 原文地址:https://www.cnblogs.com/cqumonk/p/4744488.html
Copyright © 2011-2022 走看看