Java 抽象容器类源码剖析

总体介绍

抽象容器类接口和具体容器类的关系如图所示,顶层包括Collection、List、Set、Queue、Deque和Map6个抽象容器类。

AbstractCollection:实现了Collection接口,被抽象类AbstractList、AbstractSet、AbstractQueue继承,ArrayDeque也继承自AbstractCollection。

AbstractList:父类是AbstractCollection,实现了List接口,被ArrayList、Abstract-SequentialList继承。

AbstractSequentialList:父类是AbstractList,被LinkedList继承。

AbstractMap:实现了Map接口,被TreeMap、HashMap、EnumMap继承。

AbstractSet:父类是AbstractCollection,实现了Set接口,被HashSet、 TreeSet和EnumSet继承。

AbstractQueue:父类是AbstractCollection,实现了Queue接口,被PriorityQueue继承。

本文分别介绍这些抽象类,包括它们提供的基础功能、如何实现、如何进行扩展等。

以AbstractCollection为例

AbstractCollection提供了Collection接口的基础实现,它实现了如下方法:

public boolean addAll(Collection<? extends E> c)
public boolean contains(Object o)
public boolean containsAll(Collection<?> c)
public boolean isEmpty()
public boolean remove(Object o)
public boolean removeAll(Collection<?> c)
public boolean retainAll(Collection<?> c)
public void clear()
public Object[] toArray()
public <T> T[] toArray(T[] a)
public String toString()

由于AbstractCollection不知道数据是怎么存储的,它依赖于如下更为基础的方法:

public boolean add(E e)
public abstract int size();
public abstract Iterator<E> iterator();

add方法的默认实现是:

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

代码抛出“操作不支持”异常,如果子类集合是不可被修改的,这个默认实现就可以了,否则,必须重写add方法。addAll方法的实现就是循环调用add方法。
size方法是抽象方法,子类必须重写。isEmpty方法就是检查size方法的返回值是否为0。toArray方法依赖size方法的返回值分配数组大小。
iterator方法也是抽象方法,它返回一个实现了迭代器接口的对象,子类必须重写。迭代器
定义了三个方法:

boolean hasNext();
E next();
void remove();

如果子类集合是不可被修改的,选代器不用实现remove方法,否则,三个方法都必须实现。

除了接口中的方法,Collection接口文档建议,每个Collection接口的实现类都应该提供至少两个标准的构造方法,一个是默认构造方法,另一个接受一个Collection类型的参数。

具体如何通过继承AbstractCollection来实现自定义容器呢?下面通过一个简单的例子来说明。我们使用自己实现的动态数组容器类DynamicArray来实现一个简单的Collection。

public class DynamicArray<E> {//...public E remove(int index) {E oldValue = get(index);int numMoved = size - index - 1;if(numMoved > 0)System.arraycopy(elementData, index + 1, elementData, index,numMoved);elementData[--size] = null;return oldValue;}public void add(int index, E element) {ensureCapacity(size + 1);System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}
}

基于DynamicArray,再实现一个简单的迭代器类DynamicArrayIterator

public class DynamicArrayIterator<E>  implements Iterator<E>{DynamicArray<E> darr;int cursor;int lastRet = -1;public DynamicArrayIterator(DynamicArray<E> darr){this.darr = darr;}@Overridepublic boolean hasNext() {return cursor != darr.size();}@Overridepublic E next() {int i = cursor;if(i >= darr.size())throw new NoSuchElementException();cursor = i + 1;lastRet = i;return darr.get(i);}@Overridepublic void remove() {if(lastRet < 0)throw new IllegalStateException();darr.remove(lastRet);cursor = lastRet;lastRet = -1;
}

基于DynamicArray和DynamicArrayIterator,通过继承AbstractCollection,我们来实现一个简单的容器类MyCollection。MyCollection提供了两个构造方法,并重写了size、add和iterator方法,这些方法内部使用了DynamicArray和DynamicArrayIterator。

public class MyCollection<E> extends AbstractCollection<E> {DynamicArray<E> darr;public MyCollection(){darr = new DynamicArray<>();}public MyCollection(Collection<? extends E> c){this();
addAll(c); }@Overridepublic Iterator<E> iterator() {return new DynamicArrayIterator<>(darr);}@Overridepublic int size() {return darr.size();}@Overridepublic boolean add(E e) {darr.add(e);return true;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue-Router 官网速通

前言&#xff1a;参考Vue Router&#xff0c;本文档例子使用 vue3 语法。 一&#xff1a;介绍 1. 什么是 Vue Router 是 Vue.js 的官方路由。功能包括&#xff1a;1. 路由映射。2. 动态路由。3. 路由配置。4. 路由参数。5. 过渡效果。6. 导航控制。7. CSS 类链接。8. HTML5 模…

7.1 Qt 中输入行与按钮

目录 前言&#xff1a; 技能&#xff1a; 内容&#xff1a; 参考&#xff1a; 前言&#xff1a; line edit 与pushbotton的一点联动 当输入行有内容时&#xff0c;按钮才能使用&#xff0c;并能读出输入行的内容 技能&#xff1a; pushButton->setEnabled(false) 按钮不…

166基于matlab的通过峭度指标与互相关系数筛选IMF进行SVD分解去噪

基于matlab的通过峭度指标与互相关系数筛选IMF进行SVD分解去噪&#xff0c;分辨虚假imf&#xff0c;提取最大峭度imf图。输出去噪前后时域及其包络谱结果。程序已调通&#xff0c;可直接运行。 166 matlab SVD去噪 IMF筛选 包络谱 (xiaohongshu.com)

Android安卓架构MVC、MVP、MVVM模式的概念与区别

目录 MVC框架 MVP框架 MVVM框架 MVVM与MVP区别 MVVM与MVC区别 MVC、MVP、MVVM模式哪个要好一些 MVC&#xff08;Model-View-Controller&#xff09;、MVP&#xff08;Model-View-Presenter&#xff09;、MVVM&#xff08;Model-View-ViewModel&#xff09;是三种常见的软…

Json格式文件

1.把Java对象转换成Json格式 1.1.导入依赖 这里推荐一个插件Jackson&#xff0c;其提供的类可以让Java的类转换成Jason格式文件 <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><vers…

Camtasia2023破解版下载

Camtasia2023破解版是一款简单好用的屏幕录像软件&#xff0c;它结屏幕录制和录制视频编辑等功能于一身&#xff0c;不管是用来创建视频教程还是相关教学视频或者操作演示等都是不二的选择&#xff0c;软件支持录制全屏或者部分区域进行选择录制&#xff0c;可录制网络摄像头、…

安卓实现简单砸地鼠游戏

效果 布局 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"a…

Muse专业版教程:制作简谱,制作吉他谱

UP教你制作吉他谱,muse专业版吉他谱制作过程分享_哔哩哔哩_bilibili教学讲解-小宁视频制作-狂奔的琴弦软件-Muse专业版后面会分集录从零开始制作吉他谱,感兴趣的小伙伴点一波关注, 视频播放量 15457、弹幕量 1、点赞数 208、投硬币枚数 127、收藏人数 424、转发人数 59, 视频…

函数 栈帧

函数 引用式声明(函数原型):简称声明&#xff0c;指定了函数的返回值类型、函数的接受参数类型&#xff0c;这些叫函数的签名。与变量相同&#xff0c;在函数声明时编译器不会为函数分配内存。函数的返回值类型在C99之前若不指明则默认隐式转换为为int类型&#xff0c;但在C99…

DNS服务正反解析

1.正向解析 1.配置基本 1.1防火墙配置 二者都要关闭 setenforce 0 systemctl stop firewalld #关闭防火墙 yum install bind -y #下载bind软件 客户端可以不用下 1.2服务端配置静态ip&#xff0c; ip a 查看网卡 nmcli c modify ens33 ipv4.method manual ipv4.addresses …

OpenAI发布Sora模型,可根据文字生成逼真AI视频

早在2022年11月30日&#xff0c;OpenAI第一次发布人工智能聊天机器人ChatGPT&#xff0c;随后在全世界掀起了人工智能狂潮&#xff0c;颠覆了一个又一个行业。在过去的一年多的时间里&#xff0c;chatGPT的强大功能改变了越来越多人的工作和生活方式&#xff0c;成为了世界上用…

Python教程(26)——Python迭代器和生成器详解

迭代器 Python中的迭代器是一种对象&#xff0c;它可以迭代&#xff08;遍历&#xff09;一个可迭代对象&#xff08;比如列表、元组或字符串&#xff09;的元素。迭代器用于实现迭代器协议&#xff0c;即包含 __iter__() 方法和 __next__() 方法。 迭代器的工作原理是每次调…

vue watch监听

在 Vue.js 中&#xff0c;watch 是一个对象&#xff0c;用于观察和响应 Vue 实例上的数据变化。当被监视的属性发生变化时&#xff0c;watch 里的回调函数将被调用。 &#xff08;vue2&#xff09;官方文档&#xff1a;计算属性和侦听器 — Vue.js (vuejs.org) 下面是一个简单…

数据的力量:构筑现代大型网站之数据库基础与应用

目录 数据库基础知识--前言 大型网站架构特点 DBA数据库管理员 什么是数据? 数据存储 什么是数据库 数据表的概念 为什么需要mysql这样的数据库管理工具&#xff1f;★ DBMS 收费数据库与免费数据库 运维和数据库 开发与运维的不同阶段 数据库类别 数据库具体应用…

【机器学习笔记】11 支持向量机

支 持 向 量 机 &#xff08; Support Vector Machine,SVM &#xff09; 支 持 向 量 机 是 一 类 按 监 督 学 习 &#xff08; supervisedlearning&#xff09;方式对数据进行二元分类的广义线性分类器&#xff08;generalized linear classifier&#xff09;&#xff0c;其…

C#安装CommunityToolkit.Mvvm依赖

这里需要有一定C#基础&#xff0c; 首先找到右边的解决方案&#xff0c;右键依赖项 然后选择nuget管理 这里给大家扩展一下nuget的国内源&#xff08;https://nuget.cdn.azure.cn/v3/index.json&#xff09; 然后搜自己想要的依赖性&#xff0c;比如CommunityToolkit.Mvvm 再点…

学习Android的第十四天

目录 Android DatePicker 日期选择器 DatePicker 属性 和 事件 DatePicker 事件 获得 DatePicker 的值 Android TimePicker 时间选择器 TimePicker 属性 TimePicker 事件 获得 TimePicker 的值 Android CalendarView 日历视图 CalendarView 属性 CalendarView 事件 …

Linux超详细笔记

文章目录 Linux学习笔记操作系统Linux初识Linux的诞生Linux内核Linux发行版 虚拟机VMware安装远程连接Linux系统FinalShellFinalShell连接Linux WSL配置UbuntuLinux常用命令1.入门2.ls命令cd命令3.pwd命令4.相对路径和绝对路径5.mkdir命令6.文件操作命令&#xff08;1&#xff…

vue打包优化,webpack的8大配置方案

vue-cli 生成的项目通常集成Webpack &#xff0c;在打包的时候&#xff0c;需要webpack来做一些事情。这里我们希望它可以压缩代码体积&#xff0c;提高运行效率。 文章目录 &#xff08;1&#xff09;代码压缩&#xff1a;&#xff08;2&#xff09;图片压缩&#xff1a;&…

[AIGC] Kafka 消费者的实现原理

在 Kafka 中&#xff0c;消费者通过订阅主题来消费数据。每个消费者都属于一个消费者组&#xff0c;消费者组中的多个消费者可以共同消费一个主题&#xff0c;实现分布式消费。每个消费者都会维护自己的偏移量&#xff0c;用于记录已经读取到的消息位置。消费者可以选择手动提交…