美文网首页
Java List 之 ArrayList

Java List 之 ArrayList

作者: 是归人不是过客 | 来源:发表于2021-12-03 18:57 被阅读0次

    1、ArrayList

    数据结构(动态数组、自动扩容)

    1)添加元素时容量不够
    2)新建一个数组,长度为原数组长度 * 扩充因子(1.5)。
    3)新元素放入新数组,并将数组赋值给集合,原数组丢弃。

    两个常量空数组:节省集合创建时占用的内存

    1)EMPTY_ELEMENTDATA:构造器指定了初始容器,容量不够时按1.5倍扩容
    2)DEFAULTCAPACITY_EMPTY_ELEMENTDATA:无参构造器,初次添加元素时容量默认初始化10,容量不够时按1.5倍扩容。

    EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA两个都是ArrayList的成员变量,并且都被声明为static final;更为核心的是,这两个都是空数组,那么问题来了,为什么要这样去规范呢?

        /**
         * Constructs an empty list with the specified initial capacity.
         *
         * @param  initialCapacity  the initial capacity of the list
         * @throws IllegalArgumentException if the specified initial capacity
         *         is negative
         */
        public ArrayList(int initialCapacity) {
            if (initialCapacity > 0) {
                this.elementData = new Object[initialCapacity];
            } else if (initialCapacity == 0) {
                this.elementData = EMPTY_ELEMENTDATA;
            } else {
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            }
        }
    
        /**
         * Constructs an empty list with an initial capacity of ten.
         */
        public ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        }
    
        /**
         * Constructs a list containing the elements of the specified
         * collection, in the order they are returned by the collection's
         * iterator.
         *
         * @param c the collection whose elements are to be placed into this list
         * @throws NullPointerException if the specified collection is null
         */
        public ArrayList(Collection<? extends E> c) {
            elementData = c.toArray();
            if ((size = elementData.length) != 0) {
                // c.toArray might (incorrectly) not return Object[] (see 6260652)
                if (elementData.getClass() != Object[].class)
                    elementData = Arrays.copyOf(elementData, size, Object[].class);
            } else {
                // replace with empty array.
                this.elementData = EMPTY_ELEMENTDATA;
            }
        }
    

    发现 ArrayList有三个构造函数:无参构造、给定初始容量构造、集合类中进行构造

    1)无参构造:

    无参构造时,Obeject数组elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

    2)给定初始容量构造:

    源码具体逻辑如下:
    当 传入的初始容量initialCapacity > 0为真时,创建一个大小为initialCapacity的空数组,并将引用赋给elementData;

    当 传入的初始容量initialCapacity = 0为真时,将空数组EMPTY_ELEMENTDATA赋给elementData;

    当 传入的初始容量initialCapacity < 0为真时,直接抛出IllegalArgumentException异常。

    3)集合类中进行构造:

    如果长度为0那么 elementData = EMPTY_ELEMENTDATA,否则进行拷贝

    即:

    当无参构造时,Obeject数组elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

    当有参构造时,如果给定初始容量为0,或者传入集合为空集合(不是null),那么,将空数组EMPTY_ELEMENTDATA赋给elementData;

    迭代器:fail-fast(快速失败机制)

    iterator()获取迭代器时,保存modCount(操作次数)快照,游标初始化为0.
    hasNext判断条件:cursor != size,如果有其他县城更改了集合的长度,会导致size变话,modCount和快照就会有误差。
    next()取元素时,为防止下标越界,先判断modCount和快照是否相同,不同意味着size已变话。
    如下图所示:

    .jpg

    拷贝:拷贝栈中的内容

    拷贝前后是否相互独立:(三种情况)

    基本类型:独立 在栈中分配,拷贝一份栈中的内容,因此拷贝前后的变量完全独立。
    以用类型: 不独立 栈中只记录了引用地址,拷贝一份栈中的内容,拷贝前后都是指向堆中的同一块内存。
    String: 独立 栈中记录内存地址,但是指向的内容在常量池中,如果修改该常量,不会直接修改,而是生成一个新的常量并赋值给变量,因此拷贝前后的变量指向不同的内存地址。


    .jpg

    ArraysasList:

    接收的是可变参数,基本类型不支持泛型化,会把整个数组当成一个元素放进新的数组。

    用法

    优点:

    1、支持自动改变大小
    2、可以灵活的插入元素
    3、可以灵活的删除元素

    局限:

    比一般的数组的速度慢一些;

    一、初始化:

    1、不初始化容量

    ArrayList arr1 = new ArrayList(); //不初始化刚开始的数组容量,当数组容量满时数组会自动一当前数组容量的2倍扩容
    

    2、初始化容量

    ArrayList arr2 = new ArrayList(3);//初始容量为3
    

    3、用一个集合或数组初始化

    ArrayList arr3 = new ArrayList(a);        //a为集合或数组
    

    二、添加元素
    1)add(object value;) 将指定元素object value追加到集合的末尾

    ArrayList arr = new ArrayList(); //初始化数组,下面各种方法省略初始化    
    arr.add("a");    //往数组里添加元素
    

    2)a dd(int index, Object obj);
    功能:在集合中指定index位置,添加新元素obj

    三、删除元素
    方法:remove();

    功能:从集合中删除指定位置处的元素,返回该元素

    arr.remove("a");    //在数组里删除元素(根据对象删除)
    arr.remove(0);    //根据下标删除ArrayList的元素
    

    四、替换元素

    方法:set() ;

    功能:用指定元素obj替代集合中指定index位置的元素

    arr.set(1, "10");          // 设置第2个元素为10
    

    五、clear清空
    六、查找元素
    方法:get(int index); //index -- 该元素返回的索引值
    功能:返回集合中指定位置上的元素

    import java.util.ArrayList;
    public class ArrayListDemo01 {
        public static void main(String[] args) {
            // 创建ArrayList集合
            ArrayList<String> list = new ArrayList<String>();
            // 向集合中添加元素
            list.add("stu1");
            list.add("stu2");
            list.add("stu3");
            list.add("stu4");
            // 获取集合中元素的个数
            System.out.println("集合的长度:" + list.size());
            // 取出并打印指定位置的元素
            System.out.println("第1个元素是:" + list.get(0));
            System.out.println("第2个元素是:" + list.get(1));
            System.out.println("第3个元素是:" + list.get(2));
            System.out.println("第4个元素是:" + list.get(3));
        }
    }
    

    相关文章

      网友评论

          本文标题:Java List 之 ArrayList

          本文链接:https://www.haomeiwen.com/subject/nafexrtx.html