栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ArrayList原理学习(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ArrayList原理学习(一)

ArrayList原理学习(一) ArrayList集合内置属性
// 默认的数组大小
private static final int DEFAULT_CAPACITY = 10;
// 用于空实例的共享空数组实例。
private static final Object[] EMPTY_ELEMENTDATA = {};
// 共享的空数组实例用于默认大小的空实例
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 声明一个数组
transient Object[] elementData;
// 用于记录数组里面的元素个数
private int size;
// 数组里面扩容内存的阈值,为Int类型最大范围减去8
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
// 用于记录集合修改的次数 为父类属性
protected transient int modCount = 0;
Serializable接口

​ Serializable接口为标记接口,只有实现该接口的类才能进行序列化,否则无法序列化,若在不实现该接口进行序列化会报NotActiveException异常。

ArrayList内的writeObject()方法
private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // 记录当前序列化开始时的数组修改次数
        int expectedModCount = modCount;
        // 将ArrayList中除了transient的其他数据序列化
        s.defaultWriteObject();
        // 将当前数组的元素长度序列化
        s.writeInt(size);
        // 将数组中元素逐一序列化
        for (int i=0; i 
ArrayList内的readObject()方法 
 private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // 声明一个空的数组
        elementData = EMPTY_ELEMENTDATA;
        // 将序列化的ArrayList读取出来并反序列化
        s.defaultReadObject();
        // 获取数据长度
        s.readInt(); // ignored
        if (size > 0) {
            // 校验长度 并对数组进行扩容
            ensureCapacityInternal(size);
            // 声明一个方法内元素
            Object[] a = elementData;
            // 通过循环将数据逐一反序列化读取出来
            for (int i=0; i 
Cloneable接口 

​ 该接口为标记接口,实现该接口才能实现克隆方法,否则程序会抛出异常。(克隆的前提:被克隆的对象必须实现Cloneable接口,必须重写clone方法)

public Object clone() {
    try {
    // 当用Object方法里面的clone方法,AbstractList类中是没有clone方法的,该方法的实现是由C
    // 写的
        ArrayList v = (ArrayList) super.clone();
        // 通过调用Arrays.copyOf方法进行数据的copy
        v.elementData = Arrays.copyOf(elementData, size);
        // 指定新的ArrayList集合的修改次数为0
        v.modCount = 0;
        // 返回新集合
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}
// ---------------------------Arrays类中--------------------------------
   @SuppressWarnings("unchecked")
    public static  T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
    // ==============================================
    public static  T[] copyOf(U[] original, int newLength, Class newType) {
        @SuppressWarnings("unchecked")
        // 三元校验 用于校验是生产一个默认类型的数组还是一个指定类型的数组
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        // 将原数组中数据copy到新数组中并返回新数组    
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

(注意:copy数组的内存容量与其原数组的元素个数相同)

克隆补充知识 浅拷贝和深拷贝

浅拷贝和深拷贝的区别在于拷贝对象中引用类型是否进行了copy。浅拷贝,深拷贝在对基础元素进行copy时效果相同,但在引用类型copy是浅拷贝拷贝的是索引,深拷贝则是copy引用对象后重新指定到新的引用对象。

RandomAccess接口

​ RandomAccess接口为标记接口,实现该接口的类随机遍历效率要高于顺序遍历,ArrayList实现了该接口。

// 随机访问
for (int i = 0; i < list.size(); i++) {
     // 取出集合的每一个元素
     list.get(i);
}
// 顺序访问
Iterator iterator = list.iterator();
while (iterator.hasNext()){
  iterator.next();
}

在ArrayList中随机访问效率高于顺序访问,在linkedList中顺序访问效率高于随机访问。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/336482.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号