JDK源码解析之java.util.AbstractCollection

AbstractCollection类提供了collection的实现类应该具有的基本方法,具有一定的普适性,可以从大局上了解collection实现类的主要功能。

java.util.AbstractCollection这个类提供了对接口Collection骨骼级的实现。

在这里插入图片描述

一、源码解析

1、iterator():返回一个迭代器对象

public abstract Iterator<E> iterator();

2、 size():返回集合大小

public abstract int size();

3、isEmpty():判断是否为空

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

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

5、toArray()

在函数toArray()中,首先根据collection当前的大小初始化一个数组,并根据集合大小设定期望的元素个数。而后使用迭代器依次遍历集合中的元素,如果发现集合的元素自第i个起均被删除,则直接返回r中的前i个元素。
如果发现在开始转化后,集合中插入了新的元素,则会进入:扩容+复制的循环。其中扩容部分将数组容量扩展到原来的1.5倍。当复制过程中,数组容量再次填满时,则又进行扩容。最后返回数组中所有有效的元素。

注意:该算法的复制并不是100%准确的,其只能保证其数组中元素的个数与集合迭代器遍历的元素个数相同,且顺序相同,而不是保证该数组中元素与集合元素相同。

5.1、把集合转成数组
    public Object[] toArray() {// Estimate size of array; be prepared to see more or fewer elementsObject[] r = new Object[size()];Iterator<E> it = iterator();for (int i = 0; i < r.length; i++) {if (! it.hasNext()) // fewer elements than expectedreturn Arrays.copyOf(r, i);r[i] = it.next();}return it.hasNext() ? finishToArray(r, it) : r;}
5.2、把集合转换为指定数组
    public <T> T[] toArray(T[] a) {// Estimate size of array; be prepared to see more or fewer elementsint size = size();T[] r = a.length >= size ? a :(T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);Iterator<E> it = iterator();for (int i = 0; i < r.length; i++) {if (! it.hasNext()) { // fewer elements than expectedif (a == r) {r[i] = null; // null-terminate} else if (a.length < i) {return Arrays.copyOf(r, i);} else {System.arraycopy(r, 0, a, 0, i);if (a.length > i) {a[i] = null;}}return a;}r[i] = (T)it.next();}// more elements than expectedreturn it.hasNext() ? finishToArray(r, it) : r;}
5.3、扩容然后赋值的操作,下标i和数组长度r.length相等时,就进行一次扩容,最后返回数组元素数量大小的一个数组
    private static <T> T[] finishToArray(T[] r, Iterator<?> it) {int i = r.length;while (it.hasNext()) {int cap = r.length;if (i == cap) {int newCap = cap + (cap >> 1) + 1;// overflow-conscious codeif (newCap - MAX_ARRAY_SIZE > 0)newCap = hugeCapacity(cap + 1);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) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError("Required array size too large");return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}

6、add():子类如果可以添加元素,需要重写add方法

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

7、remove(Object o):应用迭代器,移除某个元素

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

8、containsAll(Collection<?> c):是否包含指定数组的所有元素

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

9、addAll(Collection<? extends E> c):循环调用add方法

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

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

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

12、clear()清空集合所有元素

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

13、toString():重写了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(' ');}}

二、拓展

1、AbstractCollection的protected构造函数

抽象类AbstractCollection居然有protected构造函数

protected AbstractCollection() {}

关于抽象类的protected构造方法:

  • 首先,抽象类不能实例化是绝对正确的,因此抽象类中并不能包含public的构造方法;

  • 抽象类protected构造方法会被隐性调用,因此并不一定在其子类的构造方法中显示调用super(),虽然对于AbstractCollection而言是建议这么做;

  • 抽象类的protected构造方法可以用于初始化类中的某些属性,避免一场信息的出现。

2、只读集合、可修改集合

AbstractCollection将其实现类分成两种,一种为只读集合,另一种为可修改集合。

在只读集合中,只需要实现AbstractCollection中的iterator函数和size函数即可,其它的函数可以维持不变(在对性能没要求的前提下),这保证了实现类只需要少量的工作,便可以将集合的功能基本实现。

而对于可修改集合,AbstractCollection要求不仅需要实现其中的两个抽象方法,还需要实现add方法,并保证iterator函数返回的迭代器中实现了remove方法。

对于非抽象算法,AbstractCollection的建议为:如果有更加高效的实现方法,子类可以将其重写(override)

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

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

相关文章

沟通linux与windows的wine

据Netcraft网站调查&#xff0c;现在互联网上的主机有75&#xff05;以上采用Linux作为操作系统。作为服务器操作系统&#xff0c;Linux已经站稳了脚步&#xff0c;可是在桌面 操作系统上&#xff0c;还是微软的“瘟到死”一支独秀。这倒不是说Linux不好&#xff0c;很大原因我…

备份spfil、控制文件等

delete backup&#xff1b; delete backupset delete noprompt backup backup keep forver database 永久保存恢复目录中支持此命令 show parameter control 备份spfile backup spfile backup current contrlfile configure controlfile autoback …

日常问题——阿里云服务器ssh经常一段时间就断掉解决办法

#vim /etc/ssh/sshd_config 找到下面两行 #ClientAliveInterval 0 #ClientAliveCountMax 3 去掉注释&#xff0c;改成 ClientAliveInterval 30 ClientAliveCountMax 86400 这两行的意思分别是 1、客户端每隔多少秒向服务发送一个心跳数据 2、客户端多少秒没有相应&#…

在Ubuntu 8.04 LTS(hardy)下安装配置nginx和fastcgi方式的php

最近我们(瑞豪开源Xen VPS: http://www.RasHost.com)的一个客户要求在他的Ubuntu 8.04 VPS上安装一个高性能的nginx&#xff0c;下面是我的安装记录。 由于Ubuntu 804已经包含了nginx&#xff0c;所以根本不要编译&#xff0c;安装超简单&#xff01; 在VPS上修改/etc/apt/so…

apt-get包管理详解

apt-get使用source.list文件进行软件包管理。如果您想了解关于如何编辑和更新source.list中的条目的信息&#xff0c;请参阅SourcesList“起初GNU/Linux系统中只有.tar.gz。用户必须自己编译他们想使用的每一个程序。在Debian出现之後&#xff0c;人们认为有必要在系统中添 加一…

awk命令

awk是一个强大的文本分析工具&#xff0c;相对于grep的查找&#xff0c;sed的编辑&#xff0c;awk在其对数据分析并生成报告时&#xff0c;显得尤为强大。简单来说awk就是把文件逐行的读入&#xff0c;以空格为默认分隔符将每行切片&#xff0c;切开的部分再进行各种分析处理。…

ubuntu安装字符集

sudo locale-gen zh_CN.GBK sudo locale-gen zh_CN

正则表达式和grep

正则表达式(regular expression, RE)是一种字符模式&#xff0c;用于在查找过程中匹配指定的字符。 在大多数程序里&#xff0c;正则表达式都被置于两个正斜杠之间;例如/lv[o0]e/就是由正斜杠界定的正则表达式&#xff0c;它将匹配被查找的行中任何位置出现的相同模式。在正则表…

GC 垃圾回收

垃圾回收机制是由垃圾收集器Garbage Collection GC来实现的&#xff0c;GC是后台的守护进程。它的特别之处是它是一个低优先级进程&#xff0c;但是可以根据内存的使用情况动态的调整他的优先级。因此&#xff0c;它是在内存中低到一定限度时才会自动运行&#xff0c;从而实现对…

如何让你变得魅力十足

我们每个人都希望自己在某些方面对他人来说是有用的。我们渴望那种被人需要的感觉&#xff0c;觉得自己是有能力的&#xff0c;就像我们在某方面很与众不同&#xff0c;很独特一样。 有些人非常有吸引力。他们是那些每当需要帮助便会被想起的人。他们是那些另你觉得非常有帮助…

日志linux

syslog日志系统&#xff1a; syslogd 系统&#xff0c;非内核产生的信息 man 2 syslog klogd 内核&#xff0c;专门负责内核产生的信息 man 3 syslog /var/log/messages 系统标准错误日志信息&#xff0c;非内核 syslogd /var/log/dmesg klogd 共同配置文件etc/…

sysbench的安装和做性能测试

sysbench是一个模块化的、跨平台、多线程基准测试工具&#xff0c;主要用于评估测试各种不同系统参数下的数据库负载情况。关于这个项目的详细介绍请看&#xff1a;http://sysbench.sourceforge.net。它主要包括以下几种方式的测试&#xff1a;1、cpu性能2、磁盘io性能3、调度程…

加密解密

PKI public key Infrastructure 公钥基础设施 CRl 证书吊销列表 CA证书颁发机构 Certificate Authority x509 证书 包括公钥、过期时间、证书的合法拥有者、证书如何被使用 CA的信息 CA的校验码等等 Pki实现方式 TLS/ssl:x509 opengpg ssl安全的套接字层…

高性能MySQL(1)——MYSQL架构

MySQL最重要、最与众不同的特性是它的存储引擎架构&#xff0c;这种架构将查询处理与数据的存储/提取相分离&#xff0c;使得可以在使用时根据不同的需求来选择数据存储的方式。 一、Mysql逻辑架构 如果能在头脑中构建出一幅MySQL各组件之间如何协同工作的架构图&#xff0c;就…

数据库设计中的14个关键技巧

1. 原始单据与实体之间的关系  可以是一对一、一对多、多对多的关系。在一般情况下&#xff0c;它们是一对一的关系&#xff1a;即一张原始单据对应且只对应一个实体。在特殊情况下&#xff0c;它们可能是一对多或多对一的关系&#xff0c;即一张原始单证对应多个实体&#xf…

高性能MySQL(2)——Schema与数据类型的优化

良好的逻辑设计和物理设计是高性能的基石&#xff0c;应该根据系统将要执行的查询语句来设计 schema,这往往需要权衡各种因素。 一、选择优化的数据类型 MySQL支持的数据类型非常多&#xff0c;选择正确的数据类型对于获得高性能至关重要。不管 存储哪种类型的数据&#xff0c…

用户权限sudo、suid、sgid以及facl等

su 切换用户或以指定用户运行命令。 使用su可以指定运行命令的身份(user/group/uid/gid)。 为了向后兼容&#xff0c;su默认不会改变当前目录&#xff0c;且仅设置HOME和SHELL这两个环境变量(若目标用户非root&#xff0c;则还设置USER和LOGNAME环境变量)。推荐使用--login选项…

MySQL 服务器调优

关于 MySQL 调优 有 3 种方法可以加快 MySQL 服务器的运行速度&#xff0c;效率从低到高依次为&#xff1a; 替换有问题的硬件。 对 MySQL 进程的设置进行调优。 对查询进行优化。 替换有问题的硬件通常是我们的第一考虑&#xff0c;主要原因是数据库会占用大量资源。不过这…

通过脚本启动批量服务

/app/all_start_script/wwyt/此目录服务如下&#xff1a;apigateway.sh auth.sh config.sh register.sh zipkin.sh /app/all_start_script/other/此目录服务如下&#xff1a; tomcat.sh wwyt_base.sh wwyt_cache.sh wwyt_flow.sh wwyt_risk_login.sh ww…

高性能MySQL(3)——创建高性能索引

索引对于良好的性能非常关键。尤其是当表中的数据量越来越大时&#xff0c;索引对性能的影响愈发重要。 一、索引的类型 在MySQL中&#xff0c;索引是在存储引擎层而不是服务器层实现的。所以没用统一的索引标准&#xff0c;不同存储引擎的索引工作方式并不相同。 1.1、B-Tre…