Java 集合框架(2)---- List 相关类解析(上)

本文主要解析了Java集合框架中的AbstractCollection和AbstractList抽象类,讲解了它们的作用和实现原理。AbstractCollection提供了Collection接口的基础实现,子类需要实现iterator和size方法。而AbstractList针对“随机访问”数据存储提供了List接口的骨架实现,子类需要实现get和size方法以创建不可变列表,可修改列表还需重写set等方法。文章还探讨了迭代器的实现和模板方法设计模式的应用。
摘要由CSDN通过智能技术生成

本文标题大纲:

前言

在上篇文章 Java 集合框架(1)— 概述 中我们从大体上看了一下 Java 中的集合框架,包括 ListSetMap 接口的一些介绍并且解释了一些接口中声明的相关方法用法。从这篇开始,我们将一起来看一下 Java 集合框架中一些具体的类的解析,了解它们的运行原理。先从 List 接口下的相关类开始。

Java 集合框架
还是先看一下上篇文章中的那张图,我们可以看到:在 Collection 接口下有一个名为 AbstractCollection 的抽象类,而 List 接口和 Set 接口下的具体类都直接 / 间接的继承了这个抽象类,我们还是先看一下这个抽象类:

AbstractCollection

来看看官方对这个类的描述:
This class provides a skeletal implementation of the Collection interface, to minimize the effort required to implement this interface.

To implement an unmodifiable collection,
the programmer needs only to extend this class and provide implementations for the iterator and size methods.
(The iterator returned by the iterator method must implement hasNext and next.)

To implement a modifiable collection, the programmer must additionally override this class’s add method (which otherwise throws an UnsupportedOperationException), and the iterator returned by the iterator method must additionally implement its remove method.

The programmer should generally provide a void (no argument) and Collection constructor, as per the recommendation in the Collection interface specification.

The documentation for each non-abstract method in this class describes its implementation in detail. Each of these methods may be overridden if the collection being implemented admits a more efficient implementation.

大概意思是:
该类提供了 Collection 接口的骨架实现,以最小化实现该接口所需的代价。
要实现不可修改的集合,开发者只需要继承这个类并实现 iterator() 方法和 size() 方法,即返回一个迭代器(实现了 hasNextnext 方法)用于遍历集合和一个表示集合元素个数的值。
为了实现可修改的集合,开发者必须另外重写该类的 add 方法(否则抛出 UnsupportedOperationException 异常),迭代器方法返回的迭代器还必须实现其 remove 方法。
开发者通常应该根据集合接口规范中的建议提供无参构造函数和以一个集合作为参数的构造函数。
该类中的每个非抽象方法的文档详细描述了它的实现。如果所实现的集合允许更有效的实现,则可以重写这些方法。

我们可以从上面的解释中的到一些信息:
1、这个类实现了 Collection 接口并且实现了一些集合通用的方法,这样的话具体集合类就可以直接 / 间接继承这个类,对一些已经实现的并且有效的方法无需再次实现,减轻了子类的负担;
2、继承这个类的子类必须重写其 iteratorsize 这两个抽象方法,并且重写其中所有实现的方法中直接抛出了 UnsupportedOperationException 异常的方法(add 方法)。
3、如果子类可以提供更有效的方法实现,设计者鼓励开发者在子类中复写其中的一些方法,以获取更高的执行效率。

如上所述,我们可以看到 ListSet 接口的下的具体类都是直接 / 间接继承了这个抽象类。
我们来看看这个类的一些源码:

public abstract class AbstractCollection<E> implements Collection<E> {
   
    // Query Operations

    /**
     * 返回一个包含了集合中所有元素的迭代器,用于遍历集合元素
     */
    public abstract Iterator<E> iterator();

    /**
     * 返回集合中元素的数量
     */
    public abstract int size();

    /**
     * 判断集合是否为空
     */
    public boolean isEmpty() {
        return size() == 0;
    }

    /**
     * 查找当前集合中是否存在等价于参数的元素(通过 equals 方法)
     * 通过迭代器遍历集合并比对元素实现
     */
    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;
    }

    /**
     * 这个方法返回包含集合中所有元素的数组,元素顺序通过迭代器遍历指定。
     * 方法等同于:
     * List<E> list = new ArrayList<E>(size());
     * for (E e : this)
     *     list.add(e);
     * return list.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;
    }

    // Modification Operations

    /**
     * 添加参数所指定的对象到当前集合中,子类应该实现该方法
     */
    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

    /**
     * 从当前集合中移除第一个等价于参数的元素(通过 equals 方法判断等价),
     * 通过迭代器遍历集合中的元素并判断,如果移除成功返回 true,否则返回 false
     */
    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;
    }


    // Bulk Operations

    /**
     * 判断参数 c 所指向的集合中每一个元素是否都包含在当前集合中,
     * 如果是,返回 true,否则返回 false
     */
    public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

    /**
     * 将参数 c 所指向的集合中的每一个元素都添加到当前集合中,
     * 如果成功添加,返回 true,否则返回 false
     */
    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

    /**
     * 移除所有当前集合中存在于参数 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();
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值