[集合類]源碼解析4(List接口和AbstractList抽象類)

上一篇:[集合類]源碼解析3(Collection接口和AbstractCollection抽象類)

1. 概述

下面我們一起看一下List接口的定義,以及AbstractList的實現。

2. List接口

List接口繼承了Collection接口,Collection接口中的定義就不重複了,還不瞭解的給個傳送門:[集合類]源碼解析3(Collection接口和AbstractCollection抽象類)

下面我們主要看一下,List中的定義。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UHbsy87U-1575446660309)(img/image11.png)]

// 在指定位置插入    
void add(int index, E element);

// 在指定位置,按照指定集合的迭代器順序插入到當前list    
boolean addAll(int index, Collection<? extends E> c);

// 返回第index個元素    
E get(int index);

// 返回list中指定元素第一次出現的索引,沒有返回-1.最低i(o==null ?get(i)==null: o.equals(get(i))   
int indexOf(Object o);

// 返回list中指定元素最後一次出現的索引,沒有返回-1.最高i(o==null ?get(i)==null: o.equals(get(i))   
int lastIndexOf(Object o);

// 獲取list迭代器    
ListIterator<E> listIterator();

// 獲取從index索引開始的迭代器    
ListIterator<E> listIterator(int index);

// 刪除index索引對應元素    
E remove(int index);

// 暫時不管
default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }  

// 修改index索引對應元素
E set(int index, E element);

// 排序的實現,個人感覺效率有點低。先獲取數組,然後調用Arrays工具類排序,再用迭代器將排序後的元素set回去
// 我們發現Collections工具類的sort方法就是調用的這個方法來實現的。
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);
        }
    }

// 返回從fromIndex索引到toIndex索引的列表的視圖,下面會說到他的實現
List<E> subList(int fromIndex, int toIndex);

3. AbstractList

1) 迭代器

這部分我們之前已經分析過了,傳送門:[集合類] 源碼解析2(Iterator的實現)

2) 實現的方法

我們看一下圖片中的方法實現

在這裏插入圖片描述

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;

  	// 通過迭代器,查看兩個list中的每個元素是否相等
    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))) // 使用元素對象的equals方法
            return false;
    }
    return !(e1.hasNext() || e2.hasNext());
}

// hash值計算
public int hashCode() {
  	int hashCode = 1;
  	for (E e : this)
    		hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
  	return hashCode;
}

// 調用下面的方法,將由子類重寫
public boolean add(E e) {
  	add(size(), e);
  	return true;
}

// 不支持add操作
public void add(int index, E element) {
  	throw new UnsupportedOperationException();
}

// 使用foreach,語法糖(另一篇博客有講)編譯期會改成迭代器實現
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;
}

// remove,從頭到尾
public void clear() {
  	removeRange(0, size());
}

// 從前往後,查找指定元素索引,沒有返回-1
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;
}

// 從後往前,查找指定元素索引,沒有返回-1
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;
}

// 獲取迭代器
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);
}

// 不支持remove、set方法
public E remove(int index) {
  	throw new UnsupportedOperationException();
}

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

// 返回從fromIndex索引到toIndex索引的列表的視圖
// 這裏根據RandomAccess進行了一個區分,之前的博客分析過,RandomAccess是支持隨機訪問的
public List<E> subList(int fromIndex, int toIndex) {
  	return (this instanceof RandomAccess ?
          new RandomAccessSubList<>(this, fromIndex, toIndex) :
          new SubList<>(this, fromIndex, toIndex));
}

// 還有三個工具方法
// 刪除從索引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();
  	}
}

// 判斷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();
}

3) SubList

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;
    }

  /**************************************************************************/
  /*下面的方法,封裝了父列表的相關方法,進行相關檢查,考慮offset,修改size、modCount,以適應視圖*/
    public E set(int index, E element) {
        rangeCheck(index);
        checkForComodification();
        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;
    }
  
  /*************************************************************************************/

  	// 獲取視圖的listIterator
    public Iterator<E> iterator() {
        return listIterator();
    }

  	// 封裝父列表的listIterator
  	// 考慮offset,修改size、modCount,以適應視圖
    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);
    }

  	// 工具方法
  	// 檢查index合法性
    private void rangeCheck(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
  
		// 檢查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();
    }
}

// 對SubList的簡單封裝,實現RandomAccess標誌接口
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);
    }
}

下一篇:[集合類]源碼解析5(ArrayList類、Vector類和Stack類)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章