ArrayList源码(3)
来源:互联网 发布:3dmax软件打不开 编辑:程序博客网 时间:2024/06/05 05:53
前两篇写了add和remove相关的源码,现在剩下的是零散的一些和Itr、SubList、ListItr几个相关的代码,这些应用次数也多但是其中相似的代码较多。
先说零散的几个:
trimToSize()是减少存储使用的字符序列 ,如果缓冲区大于必要保持其当前的字符序列,那么它可能会调整大小,以成为更加节省空间.
public void trimToSize() { modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); }}
之后contains()方法和indexOf()、lastIndexOf()相关:
public boolean contains(Object o) { return indexOf(o) >= 0;}public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1;}public int lastIndexOf(Object o) { if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1;}
从源码中看出contains()方法是使用indexOf来进行判断是否存在,indexOf()方法是从数组头部开发对比是否有相同的,lastIndexOf()方法是从尾部开发进行对比。
public Object clone() { try { @SuppressWarnings("unchecked") ArrayList<E> v = (ArrayList<E>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); }}
clone()克隆数组,《Effective Java》的第11条中说“谨慎地覆盖clone”里面讲了很多clone的东西和注意事项,大家可以去看一眼。
我看别的博主写的:如何巧妙的使用ArrayList的Clone方法
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; i<size; i++) s.writeObject(elementData[i]); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); }}private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in array length and allocate array int arrayLength = s.readInt(); Object[] a = elementData = new Object[arrayLength]; // Read in all elements in the proper order. for (int i=0; i<size; i++) a[i] = s.readObject();}
ArrayList上重写writeObject和readObject,当其序列化的时候将会映射调用该方法。之后如果有机会学习ObjectOutputStream的源码是再仔细研究里面的具体方法使用。
零散的几个我们看了,现在我们接着看关于ArrayList的Iterator相关的源码:
public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index);}public ListIterator<E> listIterator() { return new ListItr(0);}public Iterator<E> iterator() { return new Itr();}
这是其相关的三个创建方法,其中iterator()直接创建Itr类,另外两个是创建ListItr类,这两个类是ArrayList的两个内部类其定义名为:
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; .....}private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } .....}
他们的关系是有关联的,在源码中Itr类内部的方法只有四个而且都相关:
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; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
因为我看这些方法都简单明了,其中注意一下在remove()方法中的expectedModCount = modCount;
在这里又进行了一次赋值,是因为在remove移除的时候modCount的数值发生了改变所以要重新进行复制,因为在checkForComodification()
方法中如果检测到他们两个值不相同时,这个检查是可以避免一些可能引起跌代错误的add()或remove()等危险操作。在AbstractList中,使用了一个简单的机制来规避这些风险。 这就是modCount和expectedModCount的作用所在。
在ListItr类中,其中的方法都有类似当进行改动ArrayList的时候回调用ArrayList.this.*的方法进行改变。
在subList()方法中产生了一个SubList类该类为ArrayList的内部类,其内方法和ArrayList的各种方法都是大同小异的,相当于将ArrayList的个别数据复制到一个新的List里面进行操作,而其内的方法就是这种操作的内容,但是当修改了该List的内容或者添加了其原来的ArrayList的内容是跟随着改变的,其主要形成的方法:
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 + ")");}
public void add(int index, E e) { rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset + index, e); this.modCount = parent.modCount; this.size++;}
从该方法中就能看出形成新的SubList还是从原有的ArrayList上进行改变的。
- ArrayList源码(3)
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- 【源码】ArrayList源码剖析
- JDK源码-ArrayList源码
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList LinkedList 源码分析
- java 源码ArrayList剖析
- if else多重选择结构
- 高德地图自定义定位当前位置按钮
- linux分区
- 怎么建立生态圈稳定网站排名
- Android干货
- ArrayList源码(3)
- VS2013创建C#的dll文件
- 标准c++库和stl库,boost库,qt库的总结(一)
- asp.net三种发送邮件代码(stmp,无组件邮件发送)
- 面试编程知识+算法题总结(一)
- Spring boot之读取自定义配置文件
- vue学习指南3
- 每日一题——删除无头链表的非尾节点、逆向打印单链表
- 精华【分布式微服务云架构dubbo+zookeeper+springmvc+mybatis+shiro+redis】分布式大型互联网企业架构!