AbstractCollection
用于实现基本的Collection结构,提供给普通用户继承使用。也是JDK集合类的父类,部分方法是没有被重载的。
相比Collection
接口并没有新增公开方法,但它提供了许多方法的默认实现。
public boolean contains(Object o);
提供了一个默认实现:
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
很容易理解,也很依赖于iterator()
和equals()
方法的实现
public boolean isEmpty();
public boolean isEmpty() {
return size() == 0;
}
依赖于size()
方法的实现
public Object[] 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;
}
注意该实现判断了iterator
遍历的元素个数可能跟size()
的结果不同的情况。
并且以iterator
遍历的所有元素为准。
private static T[] finishToArray(T[] r, Iterator> it);
是`toArray()`函数调用的一个私密静态方法,它将it迭代器遍历的所有元素存入一个数组,并且不依赖`size()`的实现,可以给传入的数组扩容。
```java
private static T[] finishToArray(T[] r, Iterator> it) {
private static
int i = r.length;while (it.hasNext()) { int cap = r.length;//容量capacity的概念 if (i == cap) { int newCap = cap + (cap >> 1) + 1;// n+n/2+1扩容 // overflow-conscious code if (newCap - MAX_ARRAY_SIZE > 0) newCap = hugeCapacity(cap + 1); //新容量等于Integer.MAX_VALUE或MAX_ARRAY_SIZE r = Arrays.copyOf(r, newCap); } r[i++] = (T)it.next();}// trim if overallocatedreturn (i == r.length) ? r : Arrays.copyOf(r, i);
}
### private static int hugeCapacity(int minCapacity);
是`finishToArray()`函数调用的用于容量逼近`Integer.MAX_VALUE`给数组扩容的方法
```java
private static int hugeCapacity(int minCapacity) {
//超出int范围
if (minCapacity < 0) // overflow
throw new OutOfMemoryError
("Required array size too large");
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
</code></pre>
<h2>public boolean add(E e);</h2>
<pre><code class="language-java ">public boolean add(E e) {
throw new UnsupportedOperationException();
}
</code></pre>
不允许单个添加元素。
<h2>public boolean remove(Object o);</h2>
<pre><code class="language-java ">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;
}
</code></pre>
注意<code>null</code>要分开来判断,因为<code>null</code>不能被<code>equals()</code>调用
删除的方式是通过迭代器的<code>remove()</code>方法
<h2>public boolean containsAll(Collection<?> c);
```java
public boolean containsAll(Collection> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
循环调用`contains()`方法判断
## public boolean addAll(Collection<? extends E> c)
```java
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
</code></pre>
这个操作<strong>不能保证</strong>所有元素都被添加成功了,这依赖于<code>add()</code>方法的实现,但只要有一个元素被添加成功了,就返回<code>true</code>。
<h2>public boolean removeAll(Collection<?> c)
```
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;
}
```
同理,该操作也**不能保证**所有元素都被移除成功了,但只要有一个元素被移除成功了,就返回`true`。
## public boolean retainAll(Collection> c)
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;
}
和removeAll()
的实现相反,将c中含有的元素保留了下来。
public void clear();
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
移除所有元素。
public String toString()
public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();//sb
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
以[*,*,*...]
的形式输出字符串,还考虑到了元素可能是它本身的情况
原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/abstractcollection%e9%bb%98%e8%ae%a4%e9%9b%86%e5%90%88%e7%b1%bb/