JDK源码走读(3):容器之ArrayList
来源:互联网 发布:在线seo外链工具软件 编辑:程序博客网 时间:2024/06/06 09:28
本章分析List系列中的ArrayList,有些与PriorityQueue类似,比如底层同样采取数组存储元素,也涉及到扩容操作等;也有不同之处,比如PriorityQueue不允许存入的元素为null,而ArrayList允许将null元素存放其中。
一、 类实现/继承体系结构
为了对整个List实现/继承体系有个全貌,先将体系结构图画出来:
二、 关键数据成员
(1)存储结构
transient Object[]elementData; // non-private to simplify nested class access;
以数组作为底层存储结构,存放ArrayList链表中的元素
数组elementData的默认初始化大小(DEFAULT_CAPACITY)是10。
(2)数组存放的元素个数
private int size;
三、 构造函数
ArrayList提供了多种形式的构造函数,在此不一一列举,就参数来说,主要包括,数组链表(elementData)初始化大小(initialCapacity)值、其他集合
这里要讲下以下几个构造函数:
publicArrayList (Collection<? extends E> c):利用另一个集合初始化ArrayList,要求就是负责初始化集合中的元素类型是E或者是E的子类。
四、 一些链表操作
(1) void trimToSize():将ArrayList的存储空间压缩到size大小,将空闲空间还给系统
做法就是Arrays.copyOf(elementData, size)新生成一个数组,赋值给elementData;
(2) void sort(Comparator<? super E> c):对链表进行排序,调用了Arrays.sort接口
Arrays.sort((E[])elementData, 0, size, c);
这里有一点,因为ArrayList接口都不是线程安全的,在一个线程操作链表时,并不能防止其他线程也在操作链表,有可能在排序时,其他线程已经修改了链表,修改有可能导致排序结果不准确,所以,这时就需要抛出异常:
public void sort(Comparator<?super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) { throw newConcurrentModificationException(); } modCount++; }
五、 增
(1) boolean addAll(Collection<? extends E> c):将容器c中元素添加到ArrayList的末尾
首先检查容量capacity,然后执行拷贝
Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size +numNew); // Increments modCount System.arraycopy(a, 0, elementData,size, numNew); size += numNew;
System.arraycopy参数含义:
第一个参数:数据来源数组;
第二个参数:数据来源数组的起始拷贝索引index;
第三个参数:数据目标数组;
第四个参数:数据目标数组起始拷贝索引index;
第五个参数:拷贝元素的个数;
(2) boolean addAll(int index, Collection<?extends E> c):将容器c中元素添加到ArrayList中,添加的起始位置是在index处
如果index不是数组末尾,就涉及到两次拷贝:
if (size - index > 0) System.arraycopy(elementData,index, elementData, index+numNew, numMoved); System.arraycopy(a,0, elementData, index, numNew);
六、 删
(1) E remove(int index):删除位于index位置的元素
不可避免的,会将数组elementData 在index之后元素前移一个位置,复杂度O(n)
System.arraycopy(elementData,index+1, elementData, index, numMoved);
(2) boolean removeAll(Collection<?> c):删除ArrayList中的集合c中的元素,即求交集
这里使用了一个叫做batchRemove的私有函数:
private booleanbatchRemove(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 behavioralcompatibility 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; }
七、 改
八、 查
peek():返回队列queue中index=0的元素,queue[0];如果为空,则返回null。
contains(Object o):public booleancontains(Object o) { return indexOf(o) != -1;}
九、 遍历
ArrayList实现了内部类Itr:
private class Itrimplements Iterator<E>
ArrayList还实现了内部类ListItr,其继承自Itr,并实现了接口ListIterator:
private class ListItrextends Itr implements ListIterator<E>
而接口ListIterator继承自Iterator接口:interface ListIterator<E>extends Iterator<E>
所以,可以通过两种迭代器遍历ArrayList,分别对应到Itr和ListItr:
Iterator<String>iter = names.iterator();ListIterator<String>iter = names.listIterator()/names.listIterator(1);
Itr就是通用的迭代器,提供hasNext和next接口:
public Iterator<E> iterator() { return new Itr();}
ListIterator针对ArrayList,除了提供hasNext和next接口,还提供遍历的起始点index,并且还可以逆序遍历:
public ListIterator<E> listIterator()/listIterator(index) { return new ListItr(0)/ListItr(index); } ListIterator<String> iter = names.listIterator(3); while (iter.hasPrevious()) { System.out.println(iter.previous()); }
十、 子链表subList
ArrayList实现了List<E>subList(int fromIndex, int toIndex)
List<E>subList(int fromIndex, int toIndex)接口即返回一个新生成的子链表subList对象。
- JDK源码走读(3):容器之ArrayList
- JDK源码走读之ArrayList
- JDK源码走读(2):容器之PriorityQueue
- JDK源码走读(4):容器之LinkedList
- JDK源码走读之LinkedList
- JDK源码走读之ReentrantLock
- JDK源码走读(1):开篇
- JDK源码分析之ArrayList(一)
- JDK源码分析之ArrayList(二)
- JDK源码学习之ArrayList
- JDK源码阅读之ArrayList
- JDK源码解析之ArrayList
- jdk集合源码之ArrayList
- jdk源码分析之ArrayList
- JDK之ArrayList源码解析
- JDK之ArrayList源码解读
- jdk源码剖析之ArrayList
- JDK源码解析之ArrayList
- CSS3自定义滚动条样式 -webkit-scrollbar
- View too large to fit into drawing cache, needs 6400000 bytes, only 3686400 available
- Java多线程9:ThreadLocal源码剖析
- Session 实现机制
- 兼容Android的html5移动端视频播放video自动播放/隐藏播放控件
- JDK源码走读(3):容器之ArrayList
- 第十九周—c语言 电子词典项目
- Java多线程10:ThreadLocal的作用及使用
- 素数求积
- 避免Toast多次弹出
- C++11智能指针之unique_ptr
- 中文乱码专题
- Java多线程11:ReentrantLock的使用和Condition
- 内网 外网发布