【java集合】ArrayList源码分析
2017-11-12 20:37
399 查看
ArrayList是一种基于数组实现的集合类,也是平常经常使用到的集合。其特性归纳如下:
和HashMap一样,在新建ArrzyList时可以选择是否指定容量,同样建议在可以的情况下,尽量指定一个容量,有利于提高效率。
作用是添加一个元素到列表的最后面,先看一下第一行代码:
在容量不够的情况下,对存放元素的数组进行扩容,每次新增一个长度。因为数组的长度是固定的,所以使用 Arrays.copyOf,新建一个长度是目前1.5倍的数组,并且复制原数组的数据。
ArrayList可以在指定的索引位置,添加元素:
先判断指定的索引是否有越界,和add(E element)还不一样的地方是第4行,还需要对于index之后的元素都复制到index+1的位置。
也是使用了上面提高的数组复制,把index之后的所有元素,复制到index-1,相当于向前挪了一位。
2.ArrayList的get,set,add(Element,e)的效率都很高,时间复杂为O(1)
3.ArrayList的remove,add(int index, E element),时间复杂为O(n)。如果有大量的这2个的操作,可以使用LinkedList
4.ArrayList是非线程安全的
特性 | 值 |
---|---|
是否顺序存储 | 顺序 |
是否可重复存储 | 可以 |
是否可存储null | 可以 |
是否线程安全 | 非线程安全 |
ArrayList的属性
首先列举一下ArrayList主要属性,方便大家理解和本文的说明:属性 | 说明 |
---|---|
elementData | ArrayList是基于数组实现的,这就是ArrayList用于存储 |
size | 存储元素的总数 |
threshold | 临界值,当元素数量大于thresholdthreshold,会进行扩容操作 |
新建一个ArrayList
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }
public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; }
和HashMap一样,在新建ArrzyList时可以选择是否指定容量,同样建议在可以的情况下,尽量指定一个容量,有利于提高效率。
add方法
先看一下public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
作用是添加一个元素到列表的最后面,先看一下第一行代码:
private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
在容量不够的情况下,对存放元素的数组进行扩容,每次新增一个长度。因为数组的长度是固定的,所以使用 Arrays.copyOf,新建一个长度是目前1.5倍的数组,并且复制原数组的数据。
ArrayList可以在指定的索引位置,添加元素:
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++; }
先判断指定的索引是否有越界,和add(E element)还不一样的地方是第4行,还需要对于index之后的元素都复制到index+1的位置。
get方法
get方法很简单,先判断指定的索引是否有越界,在直接返回指定索引的数据。因此ArrzyList的get方法时间复杂度是1,效率很高。public E get(int index) { rangeCheck(index); return elementData(index); }
set方法
也很简单,取出之前的元素,设置新的元素,时间复杂度也是1。public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }
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; }
也是使用了上面提高的数组复制,把index之后的所有元素,复制到index-1,相当于向前挪了一位。
总结
1.ArrayList是基于数组实现的一个集合类2.ArrayList的get,set,add(Element,e)的效率都很高,时间复杂为O(1)
3.ArrayList的remove,add(int index, E element),时间复杂为O(n)。如果有大量的这2个的操作,可以使用LinkedList
4.ArrayList是非线程安全的
相关文章推荐
- java基础提高篇--集合源码分析--jdk1.8 ArrayList源码
- Java 集合框架03---ArrayList的源码分析
- Java集合-ArrayList深入浅出源码分析
- Java 集合框架源码分析(一)——ArrayList
- java 集合ArrayList及LinkList源码分析
- java核心之集合框架——ArrayList源码分析
- Java集合之ArrayList源码分析
- Java集合源码学习(二)ArrayList分析
- Java 集合体系之 ArrayList 源码分析
- Java集合源码分析系列-(一)ArrayList源码剖析
- java源码分析之集合框架 ArrayList 03
- java集合-ArrayList和源码分析
- Java集合系列之ArrayList源码分析
- java 集合ArrayList及LinkList源码分析
- java集合03--ArrayList源码分析
- Java集合源码学习笔记(二)ArrayList分析
- java集合之ArrayList源码分析
- Java集合之ArrayList源码分析
- Java集合ArrayList实现原理——源码分析
- Java集合系列:-----------03ArrayList源码分析