ArrayList(动态数组):提供了动态的增加和减少元素

ArrayList的继承实现体系(JDK1.8)

java 动态sql foreach map_java


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.hasNext()){
    i.next();
}

Cloneable接口

package java.lang;

public interface Cloneable {

}

1.如果类没有实现Cloneable接口,调用类对象的clone方法会抛出CloneNotSupportedException

2.无法定义一个类数组实现Cloneable, 所以数组默认已经实现了Cloneable接口

3.Object提供的clone方法是浅度复制(shallow copy)

关于浅复制和深复制

java 动态sql foreach map_数组_02

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 = iterator();
        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);
    }
}