博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDK源码学习笔记——ArrayList/Vector
阅读量:5937 次
发布时间:2019-06-19

本文共 7973 字,大约阅读时间需要 26 分钟。

一、类定义

public class ArrayList
extends AbstractList
implements List
, RandomAccess, Cloneable, java.io.Serializable

二、属性

  // 序列化id    private static final long serialVersionUID = 8683452581122892189L;    // 默认初始的容量    private static final int DEFAULT_CAPACITY = 10;    // 一个空对象    private static final Object[] EMPTY_ELEMENTDATA = new Object[0];    // 一个空对象,如果使用默认构造函数创建,则默认对象内容默认是该值    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0];    // 当前数据对象存放地方,当前对象不参与序列化    transient Object[] elementData;    // 当前数组长度    private int size;    // 数组最大长度    private static final int MAX_ARRAY_SIZE = 2147483639;

三、构造方法

/**     * 注意:此时我们创建的ArrayList对象中的elementData中的长度是1,size是0,当进行第一次add的时候,elementData将会变成默认的长度:10.     */    public ArrayList() {        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;    }        /**     * 如果传入参数,则代表指定ArrayList的初始数组长度,传入参数如果是大于等于0,则使用用户的参数初始化,如果用户传入的参数小于0,则抛出异常,构造方法如下:     */    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);        }    }    /**     * 1)将collection对象转换成数组,然后将数组的地址的赋给elementData。     * 2)更新size的值,同时判断size的大小,如果是size等于0,直接将空对象EMPTY_ELEMENTDATA的地址赋给elementData     * 3)如果size的值大于0,则执行Arrays.copy方法,把collection对象的内容(可以理解为深拷贝)copy到elementData中。     * 注意:this.elementData = arg0.toArray(); 这里执行的简单赋值时浅拷贝,所以要执行Arrays,copy 做深拷贝     */    public ArrayList(Collection
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; } }

四、主要方法

// 扩容:    private void ensureExplicitCapacity(int minCapacity) {        modCount++;        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }             private void grow(int minCapacity) {        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + (oldCapacity >> 1);// 扩1.5倍        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;// 或者要求的容量        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);        elementData = Arrays.copyOf(elementData, newCapacity);    }    // get    public E get(int index) {        rangeCheck(index);        return elementData(index);    }    E elementData(int index) {        return (E) elementData[index];    }        // set    public E set(int index, E element) {        rangeCheck(index);        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }        // add    public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }        public void add(int index, E element) {        rangeCheckForAdd(index);        ensureCapacityInternal(size + 1);  // Increments modCount!!        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);        elementData[index] = element;        size++;    }        public boolean addAll(Collection
c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } public boolean addAll(int index, Collection
c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; } // remove public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); // clear to let GC do its work int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; } public boolean retainAll(Collection
c) { Objects.requireNonNull(c); return batchRemove(c, true); } private boolean batchRemove(Collection
c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }

五、内部类

private class Itr implements Iterator
// 迭代器 只能从头到尾 只有remove private class ListItr extends Itr implements ListIterator // 加强迭代器 可以指定开始位置、倒序、set、add static final class ArrayListSpliterator
implements Spliterator
// 并行迭代器 // 截取部分 还是原数组的引用,只是记录了开始结束下标 private class SubList extends AbstractList
implements RandomAcces { SubList(AbstractList
parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; } }

关于并行迭代器Spliterator:

六、其他

1.Fail-Fast机制:

 2.ArrayList与Vector区别:实现原理一样主要区别

  ①线程安全:Vector增删改查的方法都有synchronized,线程安全,但性能较ArrayList差

  ②扩容:ArrayList每次扩1.5倍(int newCapacity = oldCapacity + (oldCapacity >> 1))

      Vector默认扩成原来的2倍(int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity))

参考资料:

1.

2.

3.

转载于:https://www.cnblogs.com/hexinwei1/p/9680891.html

你可能感兴趣的文章
tomcat 8.0虚拟机配置文档
查看>>
pxc群集搭建
查看>>
JS中加载cssText延时
查看>>
常用的脚本编程知识点
查看>>
XILINX_zynq_详解(6)
查看>>
计算机网络术语总结4
查看>>
新手小白 python之路 Day3 (string 常用方法)
查看>>
soapUI的简单使用(webservice接口功能测试)
查看>>
框架 Hibernate
查看>>
python-while循环
查看>>
手机端上传图片及java后台接收和ajaxForm提交
查看>>
【MSDN 目录】C#编程指南、C#教程、ASP.NET参考、ASP.NET 4、.NET Framework类库
查看>>
jquery 怎么触发select的change事件
查看>>
angularjs指令(二)
查看>>
(原創) 如何建立一个thread? (OS) (Linux) (C/C++) (C)
查看>>
<气场>读书笔记
查看>>
领域驱动设计,构建简单的新闻系统,20分钟够吗?
查看>>
web安全问题分析与防御总结
查看>>
React 组件通信之 React context
查看>>
ZooKeeper 可视化监控 zkui
查看>>