简述AbstractCollection抽象类

本文深入解析Java集合框架的核心组件AbstractCollection,介绍其如何减少实现Collection接口的工作量,并提供默认实现方法,如isEmpty、contains等。此外,还探讨了实现不同类型的集合所需要重写的方法。

一、概述

Collection接口继承了Iterable接口,拥有了获取迭代器和循环方法,同时定义了集合基本操作方法,AbstractCollection作为Collection接口的实现类,进一步提供了其中部分方法的默认实现,简化了为实现类为重写Collection接口方法的工作量。框架关系图如下所示:
在这里插入图片描述
值得一提的是,对集合框架中各接口和抽象类的认识,有利于提升对整个集合框架的理解,有兴趣的同学还可以花几分钟简要看看以下文章:
1、简述Iterable与Iterator接口
2、简述Collection接口

二、源码

AbstractCollection抽象类提供了Collection接口的框架实现,以最小化实现此接口所需的工作量。
通过查阅源码可以了解到,AbstractCollection添加了以下几个方法的默认实现:
1、isEmpty

 public boolean isEmpty() {
        return size() == 0;
    }

2、contains

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;
    }

3、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;
    }

4、add

 public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

add方法直接抛出异常,因此不能直接调用,需要重写。

5、remove

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;
    }

6、containsAll

    public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

7、addAll

    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

8、removeAll

   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;
    }

9、retainAll

    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;
    }

10、clear

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

10、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(' ');
        }
    }

因此,如果要实现一个不可修改的集合(不需要增删操作),只需要拓展这个类并重写迭代器方法(hasNext()和next())和size()方法。
如果要实现一个可修改的集合(需要增删操作),必须要重写add方法以及迭代器的remove方法。
如果需要构造自定义的集合,可以重写其中的所有方法。

参考资料:
https://blog.youkuaiyun.com/GDUT_Trim/article/details/117572245

<think>好的,我现在需要回答用户关于Java抽象类的用途及使用场景的问题。首先,我应该回顾一下抽象类的基本概念,然后思考它在实际中的应用场景。 首先,抽象类Java中是不能被实例化的,必须由子类继承才能使用。它通常包含抽象方法,这些方法没有具体的实现,需要子类去重写。这样设计的好处是可以在抽象类中定义一些通用的方法和属性,而将具体的行为延迟到子类中实现。这符合面向对象的设计原则,比如模板方法模式,就是通过抽象类来定义算法的骨架,子类实现具体步骤。 然后,我需要考虑用户可能关心的点,比如抽象类接口的区别,因为用户之前提到了接口抽象类的问题。引用[1]中提到接口抽象类的区别,可能用户已经有一定的了解,但需要更深入的解释抽象类的具体应用场景。例如,抽象类适合用来定义一些具有共同特征和行为的类的模板,而接口更注重行为的契约。 接下来,引用[3]中提到了抽象工厂模式,虽然这里主要是讲设计模式,但可以关联到抽象类的作用。例如,抽象工厂模式中可能会使用抽象类来定义创建产品的方法,而具体工厂子类实现这些方法。这说明抽象类在框架设计中的重要性,允许定义通用的结构,具体实现由子类完成。 用户的问题可能还涉及何时选择抽象类而不是接口。根据Java的设计,抽象类适合在需要共享代码或者有状态(字段)的情况下使用,而接口更适合定义多继承的行为。例如,如果多个相关类有共同的属性或方法实现,可以将这些提取到抽象类中,避免代码重复。 然后,我需要考虑实际例子。比如Java中的InputStream是一个抽象类,它提供了读取字节流的基本方法,具体的子类如FileInputStream、ByteArrayInputStream等实现具体的读取方式。这样,抽象类定义了通用方法,子类处理具体细节,提高了代码复用性。 另外,模板方法模式是抽象类的一个典型应用。在模板方法中,抽象类定义了一个算法的步骤,其中某些步骤由子类实现。例如,咖啡和茶的制作过程可以抽象成冲泡饮料的模板方法,具体步骤如加调料由子类实现。 还要注意用户提到的使用场景。比如框架设计时,抽象类可以作为基础组件,让用户通过继承来扩展功能。Spring框架中的很多基类就是抽象类,用户可以通过继承这些类来实现自定义的行为,同时复用父类的方法。 总结一下,我需要组织内容,分点阐述抽象类的作用和使用场景,并给出实际例子。同时可能需要比较抽象类接口的区别,但用户的问题主要集中在抽象类,所以重点放在用途和场景上,适当提及区别作为补充。 需要确保回答结构清晰,使用中文,正确使用LaTeX格式,比如类名用$...$包裹,如$AbstractClass$。同时生成相关问题,帮助用户进一步学习。 最后检查是否有引用需要标注。用户提供的引用中,引用[1]提到接口抽象类的区别,引用[3]提到抽象工厂模式,这些可以在回答中适当引用,但用户的问题主要关注抽象类本身,所以引用可能作为补充信息出现。例如,在提到设计模式时引用[3],在比较接口时引用[1]。</think>### Java抽象类的作用及使用场景 #### 一、抽象类的作用 1. **定义方法模板** 抽象类允许定义**部分实现的方法**和**抽象方法**(无实现),强制子类实现特定逻辑。例如,$AbstractList$类在Java集合框架中提供了列表的基础结构,而子类如$ArrayList$需实现具体方法[^1]。 2. **代码复用与扩展性** 抽象类可以包含**公共字段和具体方法**,子类直接复用这些代码,避免重复编写。例如,$InputStream$抽象类定义了读取字节流的通用方法,子类仅需实现$read()$方法[^3]。 3. **约束子类行为** 通过抽象方法强制子类实现特定功能,例如图形类$Shape$中定义抽象方法$calculateArea()$,所有子类(如$Circle$、$Rectangle$)必须实现该方法。 4. **支持多态性** 抽象类作为基类,可通过父类引用调用子类方法,例如: ```java AbstractAnimal animal = new Dog(); animal.makeSound(); // 调用Dog类实现的makeSound() ``` --- #### 二、典型使用场景 1. **框架设计中的基础组件** **场景**:定义通用流程,允许扩展细节。 **示例**:Spring框架的$ResourceLoader$(引用[2])通过抽象类定义资源加载流程,子类如$ClassPathResource$实现具体加载逻辑。 2. **模板方法模式** **场景**:固定算法骨架,允许子类调整步骤。 **代码示例**: ```java abstract class Beverage { // 模板方法:定义算法步骤 final void prepare() { boilWater(); brew(); pourInCup(); addCondiments(); } abstract void brew(); // 子类实现具体冲泡逻辑 abstract void addCondiments(); // 子类实现添加调料 } ``` 3. **共享状态与行为** **场景**:多个子类需要共享字段或方法。 **示例**:GUI工具包中的$AbstractButton$类提供按钮的公共属性(如尺寸、颜色),子类实现具体渲染逻辑(如$Checkbox$、$RadioButton$)。 4. **部分实现接口的默认行为** **场景**:实现接口时,抽象类可提供部分方法的默认实现,减少子类冗余代码。 **示例**:$MouseAdapter$抽象类为$MouseListener$接口的空方法提供默认实现,用户只需重写需要的方法。 --- #### 三、抽象类 vs 接口 | 特性 | 抽象类 | 接口 | |---------------------|---------------------------|------------------------| | **实现方法** | 可包含具体方法和抽象方法 | Java 8+支持默认方法 | | **字段** | 可定义实例变量 | 仅静态常量 | | **继承关系** | 单继承 | 多实现 | | **设计目标** | 代码复用与层次化结构 | 定义行为契约 | --- #### 四、实际项目中的应用 - **Java集合框架**:$AbstractCollection$为所有集合类提供通用方法(如$isEmpty()$),子类只需实现核心方法(如$iterator()$)。 - **Android开发**:$AsyncTask$抽象类封装异步任务流程,开发者仅需重写$doInBackground()$等核心方法。 - **设计模式**:抽象工厂模式中,抽象类定义创建产品族的方法(引用[3]),如$GUIFactory$生成不同操作系统的界面组件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值