Collection
先上一張圖
其中:
- 實線箭頭表示繼承關係,綠色實線箭頭表示一個接口繼承另一個接口。藍色實線箭頭表示一個類繼承另外一個類。
- 綠色虛線箭頭表示實現一個接口。
Collection 接口定義
再來一張圖:
查看源碼:
public interface Collection<E> extends Iterable<E> {
// 省略....
}
可以看到他是一個泛型接口,E代表要存儲的對象類型。它繼承了Iterable接口,用於支持以迭代器Iterator的方法訪問所持有的對象。iterator()方法就是Iterable接口所定義的,用於返回Iterator對象。而Iterator接口有hasNext()和next()方法,前者用於判斷還有對象沒,後者用於獲取對象,並移動到下一位。
Collection接口定義了一些公用的方法, 比如獲取容器大小,判斷是否爲空,判斷是否包含給定的對象,轉換成數組,添加一個對象,刪除給定的對象,判斷是否包含一個給定的Collection 對象,將給定的Collection對象所包含的全部實例添加到容器中,刪除給定的Collection對象所包含的全部實例。清空容器等操作。
當然,少不了 equals(Object) 和 hashCode() 方法,他們是Object類的方法。而java中默認所有的類都繼承Object類。
同時還有stream()和parallelStream()方法。
List, Set, Queue 是 Collection 類的子接口。AbstractCollection 實現了Collection 接口。
AbstractCollection
AbstractCollection是一個抽象類。抽象類就是說它實現了部分方法。可以看到,List,Set,Queue的添加方法是不一樣的,所以它不會實現這個方法:
add(E e)
public boolean add(E e) {
throw new UnsupportedOperationException();
}
但是因爲有iterator()方法,它會返回一個Iterator對象,它抽象了訪問對象的方式,可以通過hasNext() 方法和 next() 方法的聯合使用完成對Collection持有對象的遍歷,那不管是List,Set,還是Queue, 他們判斷一個給定對象是否被包含的算法就是一樣的。
contains(Object object) 方法
public boolean contains(Object var1) {
Iterator var2 = this.iterator();
if (var1 == null) {
while(var2.hasNext()) {
if (var2.next() == null) {
return true;
}
}
} else {
while(var2.hasNext()) {
if (var1.equals(var2.next())) {
return true;
}
}
}
return false;
}
toArray()
既然能夠遍歷,那轉換成數組的算法也是一樣的。
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
toArray(T[] a)
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
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()) { // fewer elements than expected
if (a == r) {
r[i] = null; // null-terminate
} 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();
}
// more elements than expected
return it.hasNext() ? finishToArray(r, it) : r;
}
既然能夠遍歷,那就可以刪除給定對象
remove(Object o)
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;
}
containsAll(Collection<?> c)
還可以判斷是否包含給定Collection集合的所有對象。
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
addAll(Collection<? extends E> c)
還可以把給定的Collection集合的所有對象添加到自己當中,只不過是一個for循環而以,每次循環調用具體的添加方法。
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
removeAll(Collection<?> c)
可以刪除給定Collection集合的所有對象。
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<?> it = iterator();
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
retainAll(Collection<?> c)
retainAll 就是 removeAll的判斷條件取反而已。
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
clear()
清空集合就是遍歷,把找到的對象先移動到下一個對象 it.next(),然後在刪除 it.remove()。
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
toString()
藉助迭代遍歷實現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, AbstractQueue, AbstractSet
他們都會繼承AbstractCollection,同時實現自己對應的接口。比如:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements List<E> {}
public abstract class AbstractQueue<E> extends AbstractCollection<E> implements Queue<E> {}
AbstractList
要知道AbstarctList接口實現了什麼方法,就要看List和Collection相比,它多提供了些什麼方法。List和Set 和 Queue相比,它有Index這個概念。所以提供了兩個方法,如果給定一個對象,可以從前往後找,返回找到的第一個Index。indexOf(Object object), 也可以從後往前找,返回遇到的一個對象的索引 lastIndexOf(Object). 當然,正是因爲有index這個特性,List的literator 需要多那麼一點東西:返回下一個index , 返回上一個index, 判斷是否有前繼,獲取前繼。源碼如下:
public interface ListIterator<E> extends Iterator<E> {
boolean hasNext();
E next();
boolean hasPrevious();
E previous();
int nextIndex();
int previousIndex();
void remove();
void set(E var1);
void add(E var1);
}
太晚了,下次繼續。。。。