上一篇:[集合類]源碼解析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);
}
}