• java编程基础总结——18.ArrayList源码解析


    一、ArrayList概述

    实现了List接口的可扩容数组,实现了所有可选列表操作,如添加元素,包含元素等。

     从jdk1.2开始有的,学习可以参考 Collection、List、LinkedList、Vector(向量)

    注意:ArrayList和Vector功能一模一样,底层都是基于动态数组实现的
              区别:  ArrayList是非线程安全的容器
                          Vector是线程安全的容器,操作方法都加了同步锁

      

    二、 ArrayList属性

    1. private static final long serialVersionUID = 8683452581122892189L;

         是因为实现了Serializable接口,是序列号

    2. private static final int DEFAULT_CAPACITY = 10;

        ArrayList根据调用不同的构造函数,初始化容量不同

         Vector默认的容量是10

    3. private static final Object[] EMPTY_ELEMENTDATA = {};

    4.  private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

     

    三、 ArrayList构造方法

    1. 无参构造

        默认容量是0

    2. 有参构造

        除负数外,传递为多少,默认就是多。

     传入一个初始化容量,

    若初始化容量 > 0,用传入的值

    若初始化容量 = 0,空(还是相当于用传入的值)

    若初始化容量 < 0,抛出异常

    3. 有参构造 

    容量总结

       ArrayList根据调用不同的构造函数,初始化容器不同
           1).  如果使用无参的构造,默认容量是0,节约内存。 一旦添加元素,会发生第一次扩容,                    默认容量为10(后面的add方法会提到);

            2). 如果有参的构造,则传递为多少,默认就是多少

        ArrayList alist = new ArrayList();    // 默认容量0
        ArrayList alist = new ArrayList(8);    // 默认容量8

    注意:  如果在开发过程中,数据大小基本确定,建议使用有参的构造函数,减少频繁扩容,提高               性能(如存12个数,用有参构造直接一次性扩容好了;用无参构造,传第一个值触发一                   次扩容,扩容到10,传第十一个值的时候再次引发扩容)
                 当然如果不能确定的话,可以使用无参的构造。

                具体问题具体分析

    四、 ArrayList普通方法 

    1. 添加 add(){}方法

    1).  public boolean add(E e) {}

     

     

    把一个值添加到数组中。

    如果满了,进行扩容操作

    添加元素,size加1

     

     

     

     

     

     

    oldCapacity = 原有数组长度

    如果oldCapacity > 0,或者elementData不为空,进入newLength函数。prefLength = 原数组 +

    [原数组长 - (数组长度 + 1)] 和 原数组长度1.5倍的最大值。如果prefLength在0到int类型最大值-8之间(正常情况),将其返回,prefLength值作为新数组长度;如果prefLength的值非常大,则进入hugeLength,minLength = 原有数组长度 + [原数组长 - (数组长度 + 1)],如果这个数 < 0 ,即值太大,超出int的存储范围,则抛出OutOfMemoryError异常(内存耗尽);如果<=Integer.MAX_VALUE - 8,则返回Integer.MAX_VALUE - 8;否则返回minLength。将各自返回的值作为新数组长度

    如果是其他情况,如第一次扩容,则返回默认容量10 和 长度+1的最大值,创建最大值的数组长度

    2). public void add(int index, E element) {}

    根据索引添加元素。

    首先根据索引找到位置,先判断索引下标存在,不存在抛出下标越界。

    之后看是否达到容量,若达到进行扩容。进行拷贝,之后继续添加

    2.  删除remove(){}方法

    1). public boolean remove(Object o) {}

     先遍历查找,分别查找要删除的是null 或 正常值的下标位置,如果未找到,返回false,如果找到了,传入fastRemove(){}方法,如果要删除的元素不是最后一个,从i + 1位置的元素到最后一个元素拷贝到i位置到倒数第二个位置;如果要删除的元素是最后一个,置空

    2). public E remove(int index) {}

         根据下标删除元素        

     

     先用checkIndex()方法判断索引位置的合法性,如果索引 < 0,或索引 >= length ,抛出异常;如果没有异常,一直向上进行返回,继续remove中的代码,调用fastRemove(){}方法,和remove(Object o)中的一样,最后返回删除的这个值

    3.  修改方法

         public E set(int index, E element) {}

     根据下标获得值,先利用checkIndex()方法判断索引的合法性,同remove(int index)方法,若下标存在,先存储旧值,之后修改该索引的元素值为新值,最后返回旧值

    4.  查询方法

          public E get(int index) {}

     根据下标获得值,先利用checkIndex()方法判断索引的合法性,同remove(int index)方法,若下标存在,则返回对应下标的元素值

    5.  包含方法

         public boolean contains(Object o) {}

    遍历,找到为空 或 其他情况的下标,若找到,则返回下标;若找不到,则返回-1 。最后返回 返回值是否 >= 0(若是,则return true,包含;若不是,则return false,不包含)

  • 相关阅读:
    企业大数据可视化案例专题分享-入门
    Yolox
    UE4 RTS 框选功能实现
    数据库基础
    麻雀搜索算法matlab代码
    Python性能测试框架Locust实战教程!
    什么是测试架构师(经验总结)
    React 第二十四章 shouldComponentUpdate
    【PB案例学习笔记】-01创建应用、窗口与控件
    MySQL安全性策略:用户认证与数据加密
  • 原文地址:https://blog.csdn.net/m0_58679504/article/details/126170551