java源码之AbstractList

  • 前言
  • 继承关系
  • 源码
  • 成员变量
  • modCount
  • 内部类
  • 内部类Itr
  • 成员变量
  • cursor
  • lastRet
  • expectedModCount
  • 方法
  • hasNext
  • next
  • remove
  • 内部类 ListItr
  • 构造函数
  • 方法
  • hasPrevious
  • previous
  • nextIndex
  • previousIndex
  • add
  • set
  • 已实现方法
  • add
  • addAll
  • clear
  • indexOf
  • iterator
  • lastIndexOf
  • listIterator
  • subList
  • 未实现方法
  • add
  • get
  • set
  • 结束语


前言

这个类提供List接口的基础实现,对于按照顺序存储的数组优先集成这个类。
实现一个不可修改的数组仅需要实现get(int)和size()方法即可;
要是实现一个可以修改的数组必须重写set(int,E)方法(否则会抛出一个UnsupportedOperationException ),如果数组的大小是可变的必须冲写add(int, E)和remove(int)方法。

继承关系

这个类继承自AbstractCollection抽象类同时实现了List接口

源码

成员变量

modCount
protected transient int modCount = 0

这个变量被transient修饰,代表其不可被序列化,这个值记录这个数组被改变次数,用来实现fast-fail策略。如果你想自己建一个集合类你需要自行维护这个变量。

内部类

内部类Itr
private class Itr implements Iterator<E> {
        /**
         * 下一个调用next访问元素的下标
         */
        int cursor = 0;

        /**
         * 上一个访问(返回)元素的下标
         */
        int lastRet = -1;

        /**
         * 期望修改次数
         */
        int expectedModCount = modCount;
		/**
		* 判断是否包含下一个元素
		* 判断方法 是利用下一个访问元素的下边和数组的大小不同
		*/
       public boolean hasNext() {
            return cursor != size();
        }
		/**
		* 获得下一个元素
		*/
        public E next() {
        	// 判断是否修改 修改执行fail-fase策略直接抛出异常
            checkForComodification();
            try {
                // 获取当前需要获得的值下标
                int i = cursor;
                // 获取当前访问的值
                E next = get(i);
                // 将当前访问值的下标放入上一次访问中
                lastRet = i;
                //下次访问下表加1
                cursor = i + 1;
                // 返回
                return next;
            } catch (IndexOutOfBoundsException e) {
                // 抛出异常后 首先进行判断是否存在 如果存在修改就抛出ConcurrentModificationException否则就抛出NoSuchElementException
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
		/**
		* 删除当前元素
		*/
        public void remove() {
        	// 判断上次访问值
            if (lastRet < 0)
                throw new IllegalStateException();
                // 判断是否修改 修改执行fail-fase策略直接抛出异常
            checkForComodification();

            try {
            // 调用remove方法移除元素
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    //下一个要访问的下表减1 
                    cursor--;
                    // 上次访问重新归为-1
                lastRet = -1;
                // 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }
		/**
		* 判断元素是否有修改
		* 判段是利用期望修改值是否等于真实修改值
		*/
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
成员变量
cursor
int cursor = 0;

下一个要访问元素的下

  • 调用next()方法在获取到相应的元素的同时,cursor变量的数值会递增;
  • -当调用Itr.remove方法是cursor值会减1,以保证能把数据完全迭代。
lastRet
int lastRet = -1;

上一次访问的数据的下标

  • 调用next()方法也会把调用之前的cursor值赋值给lastRet;
  • 调用remove时会把他的值修改为-1,等待下次调用next()方法。
expectedModCount
int expectedModCount = modCount;

期望修改次数,在创建迭代器的时候,会把集合的modCount 数据的值放入这个变量中,之后判断这个值和集合的modCount是否相等,判断数据是否有修改,并执行fail-fase策略。

方法
hasNext
public boolean hasNext() {
            return cursor != size();
        }

判断是否仍旧存在未迭代遍历的元素,判断调教为下表是否等于集合的长度。

next
public E next() {
 			 // 判断是否存在改变
            checkForComodification();
            try {
            	// 获取当前操作的下表
                int i = cursor;
                // 调用集合的get(int)方法获取数据
                E next = get(i);
                // 将当前操作下表设置为上次访问
                lastRet = i;
                // 当前操作下标+1作为下次访问的小标
                cursor = i + 1;
                return next;
            } catch (IndexOutOfBoundsException e) {
            // 存在数组下表方法问题
            //首先判断数组是否进行了修改 存在修改就抛出ConcurrentModificationException
                checkForComodification();
                // 否则抛出NoSuchElementException
                throw new NoSuchElementException();
            }
        }

这个方法用来获取迭代器的元素,在操作开始前会先进行判断数组是否存在改动checkForComodification(),如果改动就抛出异常,为改动就进行正常访问。这个方法多次调用checkForComodification()方法

final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

判断期望修改值和数组中的修改值是否相同

remove
public void remove() {
            // 当为开始访问数或者本次访问的数据已经被删除是lastRet会为-1,此时进行判断是否有可以删除数据
            if (lastRet < 0)
                throw new IllegalStateException();
            // 判断数组是否发生改变
            checkForComodification();
            try {
            	// 调用集合的remove方法,删除数据为最近访问数据
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                // 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }
内部类 ListItr
private class ListItr extends Itr implements ListIterator<E> {
		// 构造函数
		// 从index开始进行迭代
        ListItr(int index) {
            cursor = index;
        }

		// 是否有前一个元素
        public boolean hasPrevious() {
            return cursor != 0;
        }
       //获取前一个元素
        public E previous() {
        	// 检查是否有修改元素
            checkForComodification();
            try {
                // 获取当前数据下表
                int i = cursor - 1;
                // 调用集合get方法获取数据
                E previous = get(i);
                //  lastRet 上一次访问(返回)元素的下标 调用get(i)返回的数据 所以 lastRet =i
                //  cursor 使用next方法需要返回的数据 i这个下标的数据已经被获取了 也就是下标实际位置已经不在i上了 所以再次调用next方法返回的应该是i这个下表的数据 所以cursor = i
                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) {
            if (lastRet < 0)
                throw new IllegalStateException();
            // 检查修改
            checkForComodification();

            try {
            	// 调用set修改数据
                AbstractList.this.set(lastRet, e);
                // 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

		// 在当前位置插入一个数据
        public void add(E e) {
            checkForComodification();

            try {
             // 获取当前位置
                int i = cursor;
                // 调用add方法今夕插图
                AbstractList.this.add(i, e);
                // 上次访问设置为-1
                lastRet = -1;
                // 下标+1
                cursor = i + 1;
                 // 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }
构造函数
ListItr(int index) {
            cursor = index;
        }

创造一个从index开始的ListIterator。

方法
hasPrevious
public boolean hasPrevious() {
            return cursor != 0;
        }

是否有前一个元素的判断方式是游标所处的位置是否为0;

previous
public E previous() {
        	// 检查是否有修改元素
            checkForComodification();
            try {
                // 获取当前数据下表
                int i = cursor - 1;
                // 调用集合get方法获取数据
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

获取上一个元素

nextIndex
public int nextIndex() {
        return cursor;
    }

正序访问下一个下标

previousIndex
public int previousIndex() {
            return cursor-1;
        }

获取正序访问上一个访问数据的下表

add
public void add(E e) {
            checkForComodification();

            try {
        
                int i = cursor;
                AbstractList.this.add(i, e);
                lastRet = -1;
                cursor = i + 1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

在当前位置添加一个数据

set
public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            // 检查修改
            checkForComodification();

            try {
            	// 调用set修改数据
                AbstractList.this.set(lastRet, e);
                // 修改迭代器期望值(下次调用next()不回出现ConcurrentModificationException)
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

修改当前位置的数据

已实现方法

add

在集合结尾添加一个元素调用了add(int, Object)方法,由于这个方法的实现是直接抛出一个异常所以帮他放到未实现里面

public boolean add(E e) {
        add(size(), e);
        return true;
    }
addAll

从指定的位置开始将新的集合中的元素加入集合中,同理调用add(int, Object)方法

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;
    }
clear
public void clear() {
        removeRange(0, size());
    }
     protected void removeRange(int fromIndex, int toIndex) {
     // 获取一个从fromIndex开始的ListIterator迭代器
        ListIterator<E> it = listIterator(fromIndex);
        for (int i=0, n=toIndex-fromIndex; i<n; i++) {
        // 循环调用next和remove删除
            it.next();
            it.remove();
        }
    }

删除从开始到结束的元素,利用迭代器进行删除

indexOf
public int indexOf(Object o) {
        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;
    }

获取元素所在的位置,利用ListIterator迭代器,然后根据previousIndex获得元素所在的位置

iterator
public Iterator<E> iterator() {
        return new Itr();
    }

实现为返回一个Itr实现

lastIndexOf
public int lastIndexOf(Object o) {
        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;
    }

获取元素最后出现的位置,利用ListIterator迭代器,倒叙迭代然后根据nextIndex获得位置

listIterator
  • public ListIterator listIterator(final int index)
public ListIterator<E> listIterator(final int index) {
		// 判断index是否复合范围
        rangeCheckForAdd(index);

        return new ListItr(index);
    }
    // 检测index是否在约束范围内
	private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size())
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    // 绑定IndexOutOfBoundsException保存信息
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size();
    }

获取从index开始的ListItr

  • public ListIterator listIterator()
public ListIterator<E> listIterator() {
        return listIterator(0);
    }

返回一个从0开始的ListItr

subList

生成一个从fromIndex到toIndex的集合

public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<>(this, fromIndex, toIndex) :
                new SubList<>(this, fromIndex, toIndex));
    }



class SubList<E> extends AbstractList<E> {
	// 原集合
    private final AbstractList<E> l;
    // 偏移量
    private final int offset;
    //长度
    private int size;
	//构造函数
    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;
        size = toIndex - fromIndex;
        this.modCount = l.modCount;
    }
	// 将指定位置的元素替换成指定元素
    public E set(int index, E element) {
    	// 下标范围检查
        rangeCheck(index);
        // 修改检测
        checkForComodification();
        // 修改下表为index和偏移量纸盒
        return l.set(index+offset, element);
    }
    // 获取指定下标的元素
    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;
    }
	// 获取Iterator迭代器
    public Iterator<E> iterator() {
        return listIterator();
    }
    // 获取listIterator迭代器
    public ListIterator<E> listIterator(final int index) {
    	// 修改检测
        checkForComodification();
        // 范围检测
        rangeCheckForAdd(index);
		// 返回ListIterator
        return new ListIterator<E>() {
        	// 创建一个迭代器
            private final ListIterator<E> i = l.listIterator(index+offset);
			// 重写hasNext
            public boolean hasNext() {
                return nextIndex() < size;
            }
			// 重写next
            public E next() {
                if (hasNext())
                    return i.next();
                else
                    throw new NoSuchElementException();
            }
			// 重写hasPrevious
            public boolean hasPrevious() {
                return previousIndex() >= 0;
            }
			// 重写previous
            public E previous() {
                if (hasPrevious())
                    return i.previous();
                else
                    throw new NoSuchElementException();
            }
			// 重写nextIndex
            public int nextIndex() {
                return i.nextIndex() - offset;
            }
			// 重写previousIndex
            public int previousIndex() {
                return i.previousIndex() - offset;
            }
			// 重写remove
            public void remove() {
                i.remove();
                SubList.this.modCount = l.modCount;
                size--;
            }
			// 重写set
            public void set(E e) {
                i.set(e);
            }
			// 重写add
            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);
    }
}

未实现方法

add

在指定位置插入一个元素

public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
get

获取指定位置的元素

abstract public E get(int index);
set

将指定位置重新设置成新的元素

public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

结束语

注意:迭代器只有在调用next和previous才会检测ConcurrentModificationException,在调用调用hasnext之前将集合中的数据删除到size==cursor,此时hasnext返回为false,不会调用next()方法,也就不会抛出ConcurrentModificationException。