AbstractCollection默认集合类

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) {

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/

(0)
彭晨涛彭晨涛管理者
上一篇 2019年11月18日
下一篇 2019年11月20日

相关推荐

发表回复

登录后才能评论