java arraylist源码记录

1. ArrayList 实现了RandomAccess接口, RandomAccess接口用于标记是否可以随机访问

2. 继承了AbstractList类, 因此获取了modcount , modcount用于实现快速失败机制, 如果list有修改, 那么modcount自增

3. ArrayList不支持并发, 是非线程安全的

4. 支持存放null元素

5. 扩容, 每次都是原来大小的1.5倍

public void ensureCapacity(int minCapacity) {
        //如果elementData不等于EMPTY_ELEMENTDATA(因为初始化时有可能等于), 那么minExpand为0或者DEFAULT_CAPACITY
        //如果elementData不为空minExpand为0, 可以用这个来处理minCapacity为负数的情况
        //如果elementData为空, 那么就是默认容量
        int minExpand = (elementData != EMPTY_ELEMENTDATA)
                // any size if real element table
                ? 0
                // larger than default for empty table. It‘s already supposed to be
                // at default size.
                : DEFAULT_CAPACITY;

        //如果最小容量大于minExpand, 那么进行明确扩容
        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }

    //已确定扩容minCapacity
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++; //修改次数加1

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //newCapacity为oldCapacity的1.5倍, 这里有可能会溢出为-1
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        ....
    }

6. lastIndexOf, contains, indexOf方法用于查找, 时间复杂度均为O(N), 使用对象的equals方法进行比较
7. clone() 方法为深复制, 所谓深复制和浅复制的区别在于复制内部引用对象时的不同, 深复制会将原来的对象重新clone一份, 让复制对象的引用指向新对象, 而浅复制仅仅复制引用, 仍指向原来的对象. java Object中的clone方法为浅复制

8. set() 和 get() 为O(1)的时间复杂度

9. 调用ensureCapacityInternal(int) 会使modCount+1. ArrayList中的添加元素都会调用这个函数 ,例如add(object)和add(int,Object)

10. add(Object) 和add(int,Object)的时间复杂度为O(N), 因为底层数组的复制移动

11. remove(int)方法也会使modCount+1, 时间复杂度为O(N) , 同时内部使用elementData[--size] = null;用来防止内存泄漏, 以便gc释放内存

12. remove(Object) 使用了fastRemove非法, fastRemove如果未找到删除元素, 那么modCount是不会变的, 反之modCount+1 , 之所以fastRemove称之为fast是因为使用了System.arrayCopy进行元素移动, System.arrayCopy是一个native方法, 可以躲避java访问数组时的下标检查.

13. clear方法, modCount+1

14. addAll(...) 都会调用ensureCapacityInternal方法,  从而使modCount+1, O(N)的时间复杂度

15. removeAll(object)//补集和retainAll(object)//交集 都可以使用batchRemove方法, O(N^2)的时间复杂度, modCount+1.

16. 快速失败机制体现在容器的遍历中, Iterator会在对象初始化过程中保存当前容器的modCount, 并在每次遍历检查modCount, 如果两者不一致, 那么说明容器在遍历时被修改, 抛出ConcurrentModificationException.

   private class Itr implements Iterator<E> {

        int expectedModCount = modCount;

        public E next() {
            checkForComodification();
            int i = cursor;
           ...
        }

        public void remove() {
           ...
            checkForComodification();

           ...
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
时间: 2024-12-11 02:36:55

java arraylist源码记录的相关文章

Java ArrayList源码剖析

转自: Java ArrayList源码剖析 总体介绍 ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现.除该类未实现同步外,其余跟Vector大致相同.每个ArrayList都有一个容量(capacity),表示底层数组的实际大小,容器内存储元素的个数不能多于当前容量.当向容器中添加元素时,如果容量不足,容器会自动增大底层数组的大小.前面已经提过,Java泛型只是编译器提供的语法糖,所以这里的数组是一个Object数组

Java ArrayList源码分析(有助于理解数据结构)

arraylist源码分析 1.数组介绍 数组是数据结构中很基本的结构,很多编程语言都内置数组,类似于数据结构中的线性表 在java中当创建数组时会在内存中划分出一块连续的内存,然后当有数据进入的时候会将数据按顺序的存储在这块连续的内存中.当需要读取数组中的数据时,需要提供数组中的索引,然后数组根据索引将内 存中的数据取出来,返回给读取程序.在Java中并不是所有的数据都能存储到数组中,只有相同类型的数据才可以一起存储到数组中.    因为数组在存储数据时是按顺序存储的,存储数据的内存也是连续的

Java - ArrayList源码分析

java提高篇(二一)-----ArrayList 一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小. 每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小.默认初始容量为10.随着ArrayList中元素的增加,它的容量也会不断的自动增长.在每次添加新的元素时,Array

java ArrayList 源码浅析

学习的东西越多就会发现自己越无知,最近看各种大牛的博客之类,深觉自己的无知啊,瀑布汗...摆正心态,慢慢学习,希望勤能补拙了. ArrayList算是Java集合框架中相对简单的一个了,学习数据结构的时候很多人也会选择去自己实现一个类似功能的数组的线性存储,其实ArrayList也是如此,只是其开发人员写的更加正规一些,下面就看下源码去看下他们的思路. 1. 定义 public class ArrayList<E> extends AbstractList<E> implement

Pattern类(java JDK源码记录)

1 /* 2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 * 23 *

Matcher类(java JDK源码记录)

1 /* 2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 * 23 *

PatternSyntaxException类(java JDK源码记录)

1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 */ 18 19 package java.util.regex; 20 21 /** 22 * Unchecked exception thrown to indicate a syntax error in a 23 * regular-expression pattern. 24 * 25 * @author unascribed 26 * @

JAVA Collection 源码分析(一)之ArrayList

到今天为止,差不多已经工作一年了,一直在做的是javaweb开发,一直用的是ssh(sh)别人写好的框架,总感觉自己现在高不成低不就的,所以就像看看java的源码,顺便学习一下大牛的思想和架构,read and write一直是提高自己编程水平的不二法门,写博客只是记录自己的学习历程,方便回顾,写的不好的地方,请多多包含,不喜勿喷,好了废话少说,现在让我们开始我们的历程把,Let's go!!!!!!!! 想看源码无从下手,不知道有没有跟我一样感觉的人们,今天用Intellij发现了可以找出类与

Java集合源码学习笔记(二)ArrayList分析

Java集合源码学习笔记(二)ArrayList分析 >>关于ArrayList ArrayList直接继承AbstractList,实现了List. RandomAccess.Cloneable.Serializable接口,为什么叫"ArrayList",因为ArrayList内部是用一个数组存储元素值,相当于一个可变大小的数组,也就是动态数组. (1)继承和实现继承了AbstractList,实现了List:ArrayList是一个数组队列,提供了相关的添加.删除.修