Java源码分析之ArrayList(上)
2017-08-13 22:27
411 查看
ArrayList(动态数组):提供了动态的增加和减少元素
ArrayList的继承实现体系(JDK1.8)
List接口
RandomAccess接口
RandomAccess是一个标记接口(告诉虚拟机现在已经被标记了,可以进行相应的处理了),用于标明实现此接口的List支持快速随机访问,主要目的是使算法能够在随机和顺序访问的list中表现的更加高效。标记接口这种设计从jdk1.2开始,那个时候还没有Annotation机制。所以大量使用了这种模式,到后来Java引入Annotation之后,这种标记接口的模式就用的少了,用Annotation会更加自然。而Annotation的关键字@interface也在暗示注解就是对标记接口的语法化而已
支持RandomAccess的对象,在遍历时使用get效率更高(与迭代器相比)
Cloneable接口
1.如果类没有实现Cloneable接口,调用类对象的clone方法会抛出CloneNotSupportedException
2.无法定义一个类数组实现Cloneable, 所以数组默认已经实现了Cloneable接口
3.Object提供的clone方法是浅度复制(shallow copy)
关于浅复制和深复制
Serializable接口
对象序列化的标记接口(一个类只有实现了Serializable接口,它的对象才是可序列化的)
什么情况下需要序列化?
1.当你想把内存中的对象写入到硬盘时:比如说你的内存不够用了,那计算机就要把内存里面的一部分对象暂时的保存到硬盘中,等到要用时再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如说你要把某个特定的对象保存到文件中,隔几天在把它拿出来用,那么这时就要实现Serializable接口
2.当你想用套接字在网络上传送对象时:在进行java的Socket编程时,你有时可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输
3.当你想通过RMI传输对象时:如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,把对象从B传到A,就需要实现序列化接口
Iterable接口
Collection接口
AbstractCollection类
提供了Collection接口的骨干实现
AbstractList类
提供了List接口的骨干实现(或者说List接口的最小实现)
ArrayList的继承实现体系(JDK1.8)
List接口
package java.util; import java.util.function.UnaryOperator; public interface List<E> extends Collection<E> { int size();//返回列表中的元素数 boolean isEmpty();//如果列表不包含元素,则返回 true boolean contains(Object o);//如果列表包含指定的元素,则返回 true Iterator<E> iterator();//返回按适当顺序在列表的元素上进行迭代的迭代器 Object[] toArray();//返回按适当顺序包含列表中的所有元素的数组 <T> T[] toArray(T[] a);//通过泛型约束返回指定类型的数组 boolean add(E e);//向列表的尾部添加指定的元素 boolean remove(Object o);//从列表中移除第一次出现的指定元素(如果存在) boolean containsAll(Collection<?> c);//如果列表包含指定c中的所有元素,则返回true //添加指定c中的所有元素到列表的结尾,顺序是指定c的迭代器返回这些元素的顺序 boolean addAll(Collection<? extends E> c); /*添加指定c中的所有元素到列表的index位置,把当前位置和所有后续位置向后移动(如果有的话)*/ boolean addAll(int index, Collection<? extends E> c); boolean removeAll(Collection<?> c);//从列表中移除指定c中包含的其所有元素 boolean retainAll(Collection<?> c);//仅在列表中保留指定c中所包含的元素 /* 什么是默认方法? 简单说,就是接口可以有实现方法,而且不需要实现类去实现其方法 只需在方法名前面加个default关键字即可 */ default void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final ListIterator<E> li = this.listIterator(); while (li.hasNext()) { li.set(operator.apply(li.next())); } } @SuppressWarnings({"unchecked", "rawtypes"}) default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } } void clear();//从列表中移除所有元素 /* 比较指定的对象与列表是否相等。当且仅当指定的对象也是一个列表 两个列表有相同的大小,并且两个列表中的所有相应的元素对相等时才返回true */ boolean equals(Object o); int hashCode();//返回列表的哈希码值 E get(int index);//返回列表中指定位置的元素 E set(int index, E element);//用指定元素替换列表中指定位置的元素 void add(int index, E element);//在列表的指定位置插入指定元素 E remove(int index);//移除列表中指定位置的元素 int indexOf(Object o);//返回列表中第一次出现的指定元素的索引,如果列表不包含此元素,则返回-1 int lastIndexOf(Object o);//返回列表中最后出现的指定元素的索引,如果列表不包含此元素,则返回-1 ListIterator<E> listIterator();//返回一个迭代器 ListIterator<E> listIterator(int index);//返回一个指定位置的迭代器 //返回列表中指定的fromIndex(包括)和toIndex(不包括)之间的部分 List<E> subList(int fromIndex, int toIndex); @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED); } }
RandomAccess接口
package java.util; public interface RandomAccess { }
RandomAccess是一个标记接口(告诉虚拟机现在已经被标记了,可以进行相应的处理了),用于标明实现此接口的List支持快速随机访问,主要目的是使算法能够在随机和顺序访问的list中表现的更加高效。标记接口这种设计从jdk1.2开始,那个时候还没有Annotation机制。所以大量使用了这种模式,到后来Java引入Annotation之后,这种标记接口的模式就用的少了,用Annotation会更加自然。而Annotation的关键字@interface也在暗示注解就是对标记接口的语法化而已
支持RandomAccess的对象,在遍历时使用get效率更高(与迭代器相比)
for(int i=0;i<list.size();i++){ list.get(i); } Iterator i= list.iterator(); for(i.has 4000 Next()){ i.next(); }
Cloneable接口
package java.lang; public interface Cloneable { }
1.如果类没有实现Cloneable接口,调用类对象的clone方法会抛出CloneNotSupportedException
2.无法定义一个类数组实现Cloneable, 所以数组默认已经实现了Cloneable接口
3.Object提供的clone方法是浅度复制(shallow copy)
关于浅复制和深复制
Serializable接口
package java.io; public interface Serializable { }
对象序列化的标记接口(一个类只有实现了Serializable接口,它的对象才是可序列化的)
什么情况下需要序列化?
1.当你想把内存中的对象写入到硬盘时:比如说你的内存不够用了,那计算机就要把内存里面的一部分对象暂时的保存到硬盘中,等到要用时再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如说你要把某个特定的对象保存到文件中,隔几天在把它拿出来用,那么这时就要实现Serializable接口
2.当你想用套接字在网络上传送对象时:在进行java的Socket编程时,你有时可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输
3.当你想通过RMI传输对象时:如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,把对象从B传到A,就需要实现序列化接口
Iterable接口
package java.lang; import java.util.Iterator; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; //实现这个接口允许对象成为for-each循环语句的目标 public interface Iterable<T> { Iterator<T> iterator();//返回T类型元素上的一个迭代器 default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
Collection接口
package java.util; import java.util.function.Predicate; import java.util.stream.Stream; import java.util.stream.StreamSupport; public interface Collection<E> extends Iterable<E> { int size();//返回集合中的元素数 boolean isEmpty();//如果集合不包含元素,则返回true boolean contains(Object o);//如果集合包含指定元素o,则返回true Iterator<E> iterator();//返回一个迭代器 Object[] toArray();//返回包含所有元素的数组 <T> T[] toArray(T[] a);//通过泛型约束返回指定类型的数组 boolean add(E e);//添加指定元素 boolean remove(Object o);//从集合中移除指定元素 boolean containsAll(Collection<?> c);//如果集合包含指定c中的所有元素,则返回true boolean addAll(Collection<? extends E> c);//把指定c中的所有元素添加到集合中 boolean removeAll(Collection<?> c);//移除集合中那些也包含在指定c中的所有元素 default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator<E> each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; } boolean retainAll(Collection<?> c);//仅仅保留集合中那些也包含在指定c中的所有元素 void clear();//移除集合中的所有元素 boolean equals(Object o);//比较集合与指定对象是否相等 int hashCode();//返回集合的哈希码值 @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, 0); } default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); } default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); } }
AbstractCollection类
提供了Collection接口的骨干实现
package java.util; public abstract class AbstractCollection<E> implements Collection<E> { protected AbstractCollection() {//构造方法 } public abstract Iterator<E> iterator();//返回一个迭代器 public abstract int size();//返回集合上的元素数,抽象类由子类实现 /* 直接调用子类中实现的size()方法返回大小,如果是0就就判断为空集合 */ public boolean isEmpty() { return size() == 0; } public boolean contains(Object o) { Iterator<E> it = iterator();//调用自己的iterator()方法 if (o == null) {//对o是null值进行判断(注意是等号) while (it.hasNext()) if (it.next() == null) return true; } else {//迭代器依次遍历,如果有和o一样的元素,返回true并跳出循环 while (it.hasNext()) /* 用元素所在类的equals()方法判断是否相等 所以若存入其中的元素是自定义对象 则需要重写其equals()方法 */ if (o.equals(it.next())) return true; } return false;//遍历结束仍然没有与o相同的元素就返回false } public Object[] toArray() { //估计数组的大小,可能会有更多或更少的元素(运行期可能会对集合进行添加删除操作) Object[] r = new Object[size()]; Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (!it.hasNext()) return Arrays.copyOf(r, i);//集合中的元素比预想的少 r[i] = it.next(); } return it.hasNext() ? finishToArray(r, it)/*集合中的元素比预想的多*/ : r; } @SuppressWarnings("unchecked")//这个注解作用是抑制程序中的警告 public <T> T[] toArray(T[] a) {//通过泛型约束返回指定类型的数组 int size = size(); T[] r = a.length >= size ? a : (T[]) java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size); Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (!it.hasNext()) { if (a == r) { r[i] = null; } else if (a.length < i) { return Arrays.copyOf(r, i); } else { System.arraycopy(r, 0, a, 0, i); if (a.length > i) { a[i] = null; } } return a; } r[i] = (T) it.next(); } return it.hasNext() ? finishToArray(r, it) : r; } /* 这个-8是为了减少出错的几率,避免一些机器内存溢出,最大长度依然是Integer.MAX_VALUE 并不是Integer.MAX_VALUE-8(通过hugeCapacity()方法调整) */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; @SuppressWarnings("unchecked") private static <T> T[] finishToArray(T[] r, Iterator<?> it) {//数组扩容 int i = r.length; while (it.hasNext()) { int cap = r.length; if (i == cap) { int newCap = cap + (cap >> 1) + 1; if (newCap - MAX_ARRAY_SIZE > 0)//判断数组长度是否溢出 newCap = hugeCapacity(cap + 1); r = Arrays.copyOf(r, newCap);//复制到容量为newCap的新数组中 } r[i++] = (T) it.next();//继续向数组里传值 } return (i == r.length) ? r : Arrays.copyOf(r, i);//修剪多余的长度 } private static int hugeCapacity(int minCapacity) {//重新调整最大容量 if (minCapacity < 0)//已经超过Integer.MAX_VALUE throw new OutOfMemoryError("Required array size too large"); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } /* 这个方法提供了实现,虽然只是直接抛出一个异常 如果非抽象子类不想支持这个操作的话,可以不重写这个方法 而未实现的方法子类必须实现,否则编译同不过 */ public boolean add(E e) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { Iterator<E> it = iterat 12fb1 or(); if (o == null) { while (it.hasNext()) { if (it.next() == null) { it.remove(); return true; } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); return true; } } } return false; } //这些xxxAll()方法都只是在对应xxx()方法的基础上加了一层遍历而已 public boolean containsAll(Collection<?> c) { for (Object e : c)//依次遍历c中的所有元素,若存在集合中不包含的元素,返回false if (!contains(e)) return false; return true;//否则返回true } public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } public boolean removeAll(Collection<?> c) { /*当传入的参数不是null时,返回参数本身 否则抛出一个NullPointerException异常*/ Objects.requireNonNull(c); boolean modified = false; Iterator<?> it = iterator(); /* 遍历集合中的所有元素并依次检查被遍历的元素是否在c中存在 若存在,则移除之并把标记位置为true */ while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; } public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; Iterator<E> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) {//与removeAll()方法的唯一区别 it.remove(); modified = true; } } return modified; } public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } /* Java中toString()方法的作用: toString是Object里面的方法,而所有类都继承自Object,也就是说所有对象都有这个方法 System.out.println(xx);括号里面的xx如果不是String类型的话,就会自动调用xx的toString方法 */ public String toString() { Iterator<E> it = iterator(); if (!it.hasNext())//对于空集合直接返回[] return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e);//防止出现死循环 if (!it.hasNext()) return sb.append(']').toString(); sb.append(',').append(' '); } } }
AbstractList类
提供了List接口的骨干实现(或者说List接口的最小实现)
package java.util; public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { protected AbstractList() {//构造方法 } public boolean add(E e) {//把指定元素e添加到列表的结尾 add(size(), e); return true; } abstract public E get(int index);//返回列表中指定位置的元素 public E set(int index, E element) {//用指定元素替换列表中指定位置的元素 throw new UnsupportedOperationException(); } //在列表的指定位置插入指定元素,移动当前元素和所有后续元素(如果有的话) public void add(int index, E element) { throw new UnsupportedOperationException(); } //移除列表中指定位置的元素,后续元素向左移动,返回被移除的元素 public E remove(int index) { throw new UnsupportedOperationException(); } public int indexOf(Object o) {//返回列表中第一次出现o的索引,若不包含o,返回-1 ListIterator<E> it = listIterator();//获得双向迭代器 if (o == null) { while (it.hasNext()) if (it.next() == null) return it.previousIndex(); } else { while (it.hasNext()) if (o.equals(it.next())) return it.previousIndex(); } return -1; } public int lastIndexOf(Object o) {//返回列表中最后出现o的索引,若不包含o,返回-1 ListIterator<E> it = listIterator(size()); if (o == null) { while (it.hasPrevious()) if (it.previous() == null) return it.nextIndex(); } else { while (it.hasPrevious()) if (o.equals(it.previous())) return it.nextIndex(); } return -1; } public void clear() {//移除列表中的所有元素 removeRange(0, size()); } /* 指定c中的所有元素插入到指定索引处,移动当前元素和后续元素(如果有的话) 如果列表发生更改,返回true */ public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; } public Iterator<E> iterator() {//返回一个迭代器 return new Itr(); } public ListIterator<E> listIterator() {//返回一个双向迭代器 return listIterator(0); } public ListIterator<E> listIterator(final int index) {//返回一个指定位置的双向迭代器 rangeCheckForAdd(index); return new ListItr(index); } /* 内部类实现了迭代器接口,实现了对于元素的遍历 同时也解释了不能还没有调用next就remove和不能连续两次remove的原因: 未调用next就remove,lastRet的值为-1,会抛出IllegalStateException 而在第一次调用remove后,lastRet的值会置为-1,如果再次调用remove也会抛出异常 */ private class Itr implements Iterator<E> { int cursor = 0;//游标,表示下一个要访问的元素 int lastRet = -1;//表示上一个访问的元素 int expectedModCount = modCount;//对修改次数的期望值 public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification();//检查遍历时集合有没有被修改过 fail-fast try { /* E next=get(cursor); lastRet=cursor++; return next; */ int i = cursor; E next = get(i);//获取元素 lastRet = i;//lastRet记录获取到的元素的索引 cursor = i + 1;//准备获取下一个元素 return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { //调用remove方法删除上一个访问的元素 AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; /* 删除后把lastRet置为-1,连续无间隔调用remove抛出 IllegalStateException */ lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();//并发修改异常 } } /* 支持在调用next或者previous后,添加元素 调用next时,调用add,add方法会在cursor的位置上添加元素,并把cursor+1 使得next的调用无法返回添加的元素 调用previous时,调用add,add方法会在已经返回的元素位置处添加元素,并把cursor+1 下次返回的会是cursor-1元素,即新添加的元素 */ private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { cursor = index; } public boolean hasPrevious() { return cursor != 0; } public E previous() { checkForComodification(); try { /* E previous=get(--cursor); lastRet=cursor; return previous; */ int i = cursor - 1; E previous = get(i); /* 结束方法调用时,cursor停留在返回的元素的位置上,这点与next不同 */ lastRet = cursor = i; return previous; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } public void set(E e) {//用指定元素替换next或者previous返回的最后一个元素 if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) {//插入指定元素到next返回的下一个元素的前面(如果有的话) checkForComodification(); try { int i = cursor; AbstractList.this.add(i, e); lastRet = -1; cursor = i + 1;//add方法使游标向前移动了一位 expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } } public List<E> subList(int fromIndex, int toIndex) { return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, fromIndex, toIndex)); } /* 1.判断比较对象是否为自己本身,如果是,返回true 2.判断比较对象是不是一个List,如果不是,返回false 3.迭代比较两个list公共长度上的元素,发现有不相同的返回false 4.两个list的长度不一样返回false 疑问:为什么不在循环之前判断两个list的size()是否一样,不一样直接返回false, 一样在进行循环判断比较所有元素是否相同? */ public boolean equals(Object o) {//只有两个列表的元素以及顺序完全一样才返回true if (o == this) return true; if (!(o instanceof List))//判断o这个引用真正指向的类 return false; ListIterator<E> e1 = listIterator(); ListIterator<?> e2 = ((List<?>) o).listIterator(); while (e1.hasNext() && e2.hasNext()) { E o1 = e1.next(); Object o2 = e2.next(); if (!(o1 == null ? o2 == null : o1.equals(o2))) return false; } return !(e1.hasNext() || e2.hasNext()); } public int hashCode() {//可以保证两个list相等时hashCode也相同 int hashCode = 1; for (E e : this) hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode()); return hashCode; } //移除列表中索引在fromIndex(包含)和toIndex(不包含)之间的所有元素 protected void removeRange(int fromIndex, int toIndex) { ListIterator<E> it = listIterator(fromIndex); for (int i = 0, n = toIndex - fromIndex; i < n; i++) { it.next(); it.remove(); } } protected transient int modCount = 0;//transient关键字表明不可被序列化 private void rangeCheckForAdd(int index) {//边界检查 if (index < 0 || index > size()) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: " + index + ", Size: " + size(); } } class SubList<E> extends AbstractList<E> { private final AbstractList<E> l;//持有原集合对象的引用 private final int offset; private int size; //SubList并不是独立的,修改SubList也就等于修改了List中的元素 SubList(AbstractList<E> list, int fromIndex, int toIndex) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > list.size()) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); l = list; offset = fromIndex;//offset:偏移 size = toIndex - fromIndex; this.modCount = l.modCount; } public E set(int index, E element) { rangeCheck(index); checkForComodification(); return l.set(index + offset, element);//可以通过更改SubList来改变原集合对象 } public E get(int index) { rangeCheck(index); checkForComodification(); return l.get(index + offset); } public int size() { checkForComodification(); return size; } public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); l.add(index + offset, element); this.modCount = l.modCount; size++; } public E remove(int index) { rangeCheck(index); checkForComodification(); E result = l.remove(index + offset); this.modCount = l.modCount; size--; return result; } protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); l.removeRange(fromIndex + offset, toIndex + offset); this.modCount = l.modCount; size -= (toIndex - fromIndex); } public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); int cSize = c.size(); if (cSize == 0) return false; checkForComodification(); l.addAll(offset + index, c); this.modCount = l.modCount; size += cSize; return true; } public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); return new ListIterator<E>() {//匿名内部类 private final ListIterator<E> i = l.listIterator(index + offset); public boolean hasNext() { return nextIndex() < size; } public E next() { if (hasNext()) return i.next(); else throw new NoSuchElementException(); } public boolean hasPrevious() { return previousIndex() >= 0; } public E previous() { if (hasPrevious()) return i.previous(); else throw new NoSuchElementException(); } public int nextIndex() { return i.nextIndex() - offset; } public int previousIndex() { return i.previousIndex() - offset; } public void remove() { i.remove(); SubList.this.modCount = l.modCount; size--; } public void set(E e) { i.set(e); } public void add(E e) { i.add(e); SubList.this.modCount = l.modCount; size++; } }; } public List<E> subList(int fromIndex, int toIndex) { return new SubList<>(this, fromIndex, toIndex); } private void rangeCheck(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void rangeCheckForAdd(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: " + index + ", Size: " + size; } private void checkForComodification() { if (this.modCount != l.modCount) throw new ConcurrentModificationException(); } } class RandomAccessSubList<E> extends SubList<E> implements RandomAccess { RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) { super(list, fromIndex, toIndex); } public List<E> subList(int fromIndex, int toIndex) { return new RandomAccessSubList<>(this, fromIndex, toIndex); } }
相关文章推荐
- Java集合源码分析系列-(一)ArrayList源码剖析
- java8源码分析ArrayList
- 【java集合】ArrayList源码分析
- Java集合源码分析(二)ArrayList
- java 集合ArrayList及LinkList源码分析
- Java ArrayList 源码分析与提高性能替代方案
- ArrayList源码分析-java8
- Java容器类源码-ArrayList的最全的源码分析
- Java ArrayList源码分析
- Java集合-ArrayList深入浅出源码分析
- 分析Java中ArrayList与LinkedList列表结构的源码
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
- Java源码分析之ArrayList
- 【Java源码分析】ArrayList源码分析
- Java concurrent Framework并发容器之CopyOnWriteArrayList(1.6)源码分析
- Java容器类源码-ArrayList的最全的源码分析
- java集合03--ArrayList源码分析
- Java中ArrayList源码深入分析(JDK1.6)
- Java源码分析-ArrayList
- java 集合ArrayList及LinkList源码分析