Java集合系列(四)AbstractCollection 抽象类

public abstract class AbstractCollection<E> extends Object implements Collection<E>
复制代码

所有的子类:

AbstractList, AbstractQueue, AbstractSet, ArrayDeque, ConcurrentLinkedDeque

文档: 此类提供集合接口的骨骼(框架、概要)实现, 以最小化实现此接口所需的工作量。 为了实现不可修改集合, 程序员只需扩展此类并为 iteratorsize方法提供实现。(迭代器方法返回的迭代器必须实现 hasNext 和next 方法)。

为了实现可修改的集合, 程序员必须另外重写此 类 add 方法(否则将引发 UnsupportedOperationException), 迭代器方法返回的迭代器必须另外实现其remove 方法

程序员通常应根据集合接口规范中的建议提供void(no argument) 和 collection构造函数。

此类中的每个非抽象方法的文档详细描述了其实现。如果正在实现的集合承认更有效的实现, 则这些方法中的每一个都可能被重写。

从 java.lang.Object 继承的方法 clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait 从 java.util.Collection 接口继承的方法 equals, hashCode, parallelStream, removeIf, spliterator, stream 从 java.lang.Iterable 继承的方法 forEach

我们看看源码:

public abstract class AbstractCollection<E> implements Collection<E> {
    /**
     * Sole constructor.  (For invocation by subclass constructors, typically
     * implicit.)
     * 构造方法,用于子类调用,通常是隐式的。我们知道 抽象类可以有自己的构造方法,但是不能被实例化,抽象类的构造
     * 方法通常用于子类初始化
     */
    protected AbstractCollection() {
    }
	
	// 前面我们从文档中知道,如果要实现自己的不可修改的实现类,那么需要实现iterator() 和 size() 方法。
	public abstract Iterator<E> iterator();
    public abstract int size();
	
	// 判空
    public boolean isEmpty() {
        return size() == 0;
    }
	// 是否包含某个对象,内部使用迭代器实现遍历
    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())
	        // 这里有一个小技巧,通常我们使用 equals 方法,前面的对象不能为空,否则就NPE了,所以这里首先判断了 o == null
	        // && 和 || 也有这样的妙用,可以有效的避免一些异常。
            if (o.equals(it.next()))
                return true;
    }
    return false;
	}

	// 转数组
    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;
    }

	// 前面文档中说,如果我们要实现自己的可以修改元素的集合类,那么需要实现 add 方法,否则会抛出 UnsupportedOperationException
    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

	// 移除对象
    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;
    }
	
	// 是否包含另外一个集合
    public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

	// 添加一个集合
    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

	// 移除所有指定元素
    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;
    }

	// 清空集合
    public void clear() {
        Iterator<E> it = iterator();
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
    }

    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(' ');
        }
    }
}
复制代码

从代码中我们看到,在 AbstractCollection 抽象类中,完善了大部分常用的方法,具体的方法使用展示,我们在上一篇笔记 Collection 接口中已经展示了。这些常用方法的实现,是子类在继承的时候,只需要实现自己的 add ,size , iterator 以及 iterator 中的 remove 方法,大大的减小了工作量。这也是 抽象类存在的重要意义之一。

另外,add 方法没有定义为抽象类,而且直接在 add 方法中抛出了异常。为什么这么做呢?因为不是每一个集合类都需要 add 方法,抽象类不应该有子类不需要的抽象方法。另外,如果我们要实现可修改的集合,那么我们就必须实现 add 方法,否则,视为集合不可变,就应该在 add 方法中抛出异常。

转载于:https://juejin.im/post/5b502ccfe51d455d947157fe

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值