版本 jdk-7u71-windows-x64
JavaSE7 ArrayList源码上:http://flyouwith.iteye.com/blog/2166890
/** * 从这个列表中移除所有c中包含元素 */ public boolean removeAll(Collection<?> c) { return batchRemove(c, false); } /** * 只保留包含在这个列表中的元素 */ public boolean retainAll(Collection<?> 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++) //*****注意这种在集合中删除n多元素的逻辑***** if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // 明确让GC做它的工作 for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; } /** * 私有,不知道留着干嘛用的 * 序列化ArrayList的实例 */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ int expectedModCount = modCount; s.defaultWriteObject(); s.writeInt(size); for (int i=0; i<size; i++) { s.writeObject(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } /** * 重建实例 * 反序列化ArrayList的实例 */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { elementData = EMPTY_ELEMENTDATA; s.defaultReadObject(); s.readInt(); if (size > 0) { ensureCapacityInternal(size); Object[] a = elementData; for (int i=0; i<size; i++) { a[i] = s.readObject(); } } } /** * 返回一个指向数组索引index处的ListIterator */ public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); } /** * 返回一个指向数组起始处的ListIterator */ public ListIterator<E> listIterator() { return new ListItr(0); } /** * 返回一个指向数组起始处的iterator */ public Iterator<E> iterator() { return new Itr(); } /** * 此为内部类,是ArrayList,iterator的具体实现 */ private class Itr implements Iterator<E> { int cursor; // 下一个元素的索引,初始0 int lastRet = -1; // 当前返回元素的索引,初始-1,没有可返回的元素 //这个元素的作用出来了,在进行迭代的时候 //如果有改变modCount值的方法执行,那么就会抛出异常 //看这个内部类的最后一个方法 int expectedModCount = modCount; //判断下一个元素是否存在,返回false循环退出 public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification();//检核 int i = cursor; if (i >= size)//检核 throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length)//检核 throw new ConcurrentModificationException(); cursor = i + 1; //在next()取值时 ,计算下一个索引 return (E) elementData[lastRet = i]; } //删除lastRet索引处元素 public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { //上面介绍过的方法 ArrayList.this.remove(lastRet); //上面方法执行后,cursor下一个索引位置前移 cursor = lastRet; //一次next()只允许删除一次元素 lastRet = -1; //因为执行删除modCount值改变。重新赋值 expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //检核 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } /** * 内部类,是ArrayList,ListIterator的具体实现 * 注意这里继承了上面的向后迭代器 * 所以这个迭代器可以向前和向后迭代 */ private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); //构造方法,初始化索引位置 cursor = index; } // 判断上一个元素是否存在,只要不等于零就一定存在前一个元素 public boolean hasPrevious() { return cursor != 0; } // 下一个元素索引 public int nextIndex() { return cursor; } // 上一个元素索引 public int previousIndex() { return cursor - 1; } //返回上一个元素 @SuppressWarnings("unchecked") public E previous() { checkForComodification();//检核 int i = cursor - 1; //上一个元素索引 if (i < 0)//检核 throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length)//检核 throw new ConcurrentModificationException(); cursor = i;//这里就有意思了 return (E) elementData[lastRet = i]; } //替换当前索引处的元素 public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //在当前索引处添加元素 public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }
就上面的listIterator写个小程序看看
public static void main(String[] args) throws IOException{ //初始化 ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","d","e")); //从2位置("d")开始迭代 ListIterator<String> iter = list.listIterator(2); //cursor=2 iter.add("c");//在d位置插入c,d、e后移一位 //cursor=3 if(iter.hasPrevious()){ //向前迭代 //cursor=3 System.err.println(iter.previous());//elementData[2] //cursor=2 } if(iter.hasNext()){ //向后迭代 //cursor=2 System.err.println(iter.next()); //elementData[2] //cursor=3 } if(iter.hasPrevious()){ //向前迭代 //cursor=3 System.err.println(iter.previous());//elementData[2] //cursor=2 } if(iter.hasNext()){ //向后迭代 //cursor=2 System.err.println(iter.next()); //elementData[2] //cursor=3 } while(iter.hasNext()){ System.out.println(iter.next()); } }
输出:
c
c
c
c
d
e
继续源码
/** * 截取一段数据,生成一个新的List。 * 如果原数组(列表)太大,可以截取出一段来进行操作。 * 其实就是对原数组(列表)的某一段的操作,改变哪一个另一个都会改变 */ public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); } static void subListRangeCheck(int fromIndex, int toIndex, int size) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > size) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } /** * 继承了AbstractList 所以具有所有List的功能 * 但是操作的依然是源数据 * 下面方法基本都是通过操作索引大小来调用外部类的方法操作源数组 * 没什么意思。。不介绍了 */ private class SubList extends AbstractList<E> implements RandomAccess { private final AbstractList<E> parent; private final int parentOffset; private final int offset; int size; SubList(AbstractList<E> 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; } public E set(int index, E e) { rangeCheck(index); checkForComodification(); E oldValue = ArrayList.this.elementData(offset + index); ArrayList.this.elementData[offset + index] = e; return oldValue; } public E get(int index) { rangeCheck(index); checkForComodification(); return ArrayList.this.elementData(offset + index); } public int size() { checkForComodification(); return this.size; } public void add(int index, E e) { rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset + index, e); this.modCount = parent.modCount; this.size++; } public E remove(int index) { rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); this.modCount = parent.modCount; this.size--; return result; } protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex); this.modCount = parent.modCount; this.size -= toIndex - fromIndex; } public boolean addAll(Collection<? extends E> c) { return addAll(this.size, c); } public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); int cSize = c.size(); if (cSize==0) return false; checkForComodification(); parent.addAll(parentOffset + index, c); this.modCount = parent.modCount; this.size += cSize; return true; } public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); final int offset = this.offset; return new ListIterator<E>() { int cursor = index; int lastRet = -1; int expectedModCount = ArrayList.this.modCount; public boolean hasNext() { return cursor != SubList.this.size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= SubList.this.size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[offset + (lastRet = i)]; } public boolean hasPrevious() { return cursor != 0; } @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[offset + (lastRet = i)]; } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { SubList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = ArrayList.this.modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(offset + lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { int i = cursor; SubList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = ArrayList.this.modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (expectedModCount != ArrayList.this.modCount) throw new ConcurrentModificationException(); } }; } public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, offset, fromIndex, toIndex); } private void rangeCheck(int index) { if (index < 0 || index >= this.size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void rangeCheckForAdd(int index) { if (index < 0 || index > this.size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+this.size; } private void checkForComodification() { if (ArrayList.this.modCount != this.modCount) throw new ConcurrentModificationException(); } }
补充一下 ArrayList 实现了一个RandomAccess标记接口
如果集合类是RandomAccess的实现,则尽量用for(int i = 0; i < size; i++) 来遍历而不要用Iterator迭代器来遍历,在效率上要差一些。反过来,如果List是Sequence List,则最好用迭代器来进行迭代。
在对List特别是Huge size的List的遍历算法中,要尽量来判断是属于RandomAccess还是Sequence List,因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大。
相关推荐
JDK8的ArrayList源码文件
本文主要介绍了Java中ArrayList类的源码解析,具有很好的参考价值。下面跟着小编一起来看下吧
本资源根据个人学习和总结,主要介绍Java中ArrayList扩容机制源码的解析,主要包含文字和代码等内容,以源码的形式进行分析,详细介绍了ArrayList扩容机制的整个流程,特此将该资源分享
Java 集合框架(2_9)-Collection - ArrayList 源码解析
主要为大家详细介绍了Java集合框架ArrayList源码分析,感兴趣的小伙伴们可以参考一下
java arraylist 源码
ArrayList源码阅读笔记 -- 介绍了ArrayList 普通增删改查的过程,从构造空参构造方法,然后添加元素,修改元素,删除元素,获取元素.
ArrayList的Java源代码,可供开发者查看阅读,希望对大家有用,同时可以参看个人博文,便于理解。https://blog.csdn.net/la859962513/article/details/82752510
总体介绍 ...前面已经提过,Java泛型只是编译器提供的语法糖,所以这里的数组是一个Object数组,以便能够容纳任何类型的对象。 size(), isEmpty(), get(), set()方法均能在常数时间内完成,add
java arraylist源码泛型示例 Java源代码程序,通过使用应用于ArrayList的用户定义的数据类型来演示泛型概念的示例
arraylist源码带有JAVA的多媒体设备租赁应用程序(ArrayList) 这是带有ArrayList存储方法或临时数据存储的多媒体工具租赁应用程序的源代码。 Java编程语言。 使用NetBeans IDE应用程序。 这是屏幕截图结果:
java arraylist源码数据结构算法 使用Java编程语言的数据结构和算法源代码(包括Stack,LinkedList,ArrayList,Queue和Binary Tree)
本文对JAVA ArrayList做了详细介绍,文中学到了ArrayList源码解析、ArrayList遍历方式、toArray()异常,最后给出了ArrayList示例。
主要介绍了Java编程中ArrayList源码分析,具有一定借鉴价值,需要的朋友可以参考下。
ArrayList是list接口下一个底层用数组实现的典型list类,也就是传说中的动态数组,用MSDN的说法就是array的复杂版本,它提供了动态的增加和减少元素,实现了ICollection和IList接口,灵活的设置数组的大小等好处。...
现在由大恶人付有杰来从增删改查几个角度轻度解析ArrayList的源码 首先ArrayList的底层数据结构非常简单,就是一个数组。 从源码第115行我们可以得出信息,他的默认数组长度是10。 /** * Default initial capacity...
计算机后端-Java-Java核心基础-第24章 集合01 14. ArrayList的源码分析.avi
能学到什么:ArrayList的源码分析,自动扩容和自动缩容的源码分析,相关参数的深度解析,从是什么,为什么,怎么做三个角度进行讲解,用通俗易懂的白话进行介绍,LinkedList和Vector以及ArrayList的区别以及使用场景...
Map+List+ArrayList+LinkedList Java源代码,适合初学者