一、List接口
有序集合(也稱爲序列)。該界面的用戶可以精確控制列表中每個元素的插入位置。用戶可以通過整數索引(列表中的位置)訪問元素,並搜索列表中的元素。
與集合不同,列表通常允許重複的元素(包括空元素)。列表界面除了Collection中指定的附加條款之外,還添加了迭代器,add,remove,equals和hashCode方法。
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean addAll(int index, Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
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);
int lastIndexOf(Object o);
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex);
//JDK1.8新增內容
/*將該列表的每個元素替換爲將該運算符應用於該元素的結果。運營商拋出的錯誤或運行時異常被轉發給呼叫者。*/
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
/*根據指定的比較器引起的順序排列此列表。此列表中的所有元素必須使用指定的比較器相互比較
如果指定的比較器爲null,則該列表中的所有元素都必須實現Comparable接口,並且應該使用元素的自然排序。*/
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);
}
}
//用於並行遍歷
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
}
二、AbstractList抽象類
該類提供了List接口的骨架實現。如果要修改的列表,必須另外覆蓋set(int,E)方法(否則會拋出UnsupportedOperationException)。如果改變列表的大小,則必須另外覆蓋add(int,E)和remove(int)方法。與其他抽象集合實現不同,程序員不必提供迭代器實現;迭代器和列表迭代器由這個類實現,在“隨機訪問”方法之上:get(int),set(int,E),add(int,E)和remove(int)。
2.1 實現的方法
protected AbstractList() {
}
//重寫AbstractCollection中的add方法,向List集合中添加元素
// java接口和父類中有相同的方法,如果子類不想重寫,那麼可以不重寫,那麼實現接口的方法,就相當於父類的方法繼承下來。
public boolean add(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) {
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) {
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());
}
/*將指定集合中的所有元素插入到此列表中的指定位置(可選操作)。 將當前處於該位置的元素(如果有的話)和隨後的任何元素移動到右邊(增加其索引)。*/
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;
}
//將指定的對象與此列表進行比較以獲得相等性。 如果且僅當指定的對象也是列表時,則返回true,兩個列表的大小相同,並且兩個列表中所有相應的元素對都相等。
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
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() {
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;
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();
}
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);
}
//返回此列表中指定的fromIndex(包括)和toIndex之間的獨佔視圖。 public List<E> subList(int fromIndex, int toIndex) { return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, fromIndex, toIndex)); }
2.2 迭代器
2.2.1 Irt迭代器
Itr實現了Iterator接口,主要功能是判斷當前迭代器的位置(next())、進行刪除操作(remove())、防止多迭代器或者多線程操作時的影響(checkForComodification())。
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();
try {
int i = cursor;
E next = get(i);
//由最近的呼叫返回到下一個或上一個的元素的索引。
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
能用圖說明問題,就不扯白話:2.2.2 ListItr迭代器
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public E previous() {
checkForComodification();
try {
int i = cursor - 1;
E previous = get(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 {
AbstractList.this.set(lastRet, e);
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
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();
}
}
}
previous()過程:
add()過程: