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,一经查实,立即删除!

相关文章

GC 垃圾回收

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

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

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

高性能MySQL(4)——查询性能优化

査询优化、索引优化、库表结构优化需要齐头并进&#xff0c;一个不落。 一、为什么查询速度为变慢 在尝试编写快速的查询之前,需要清楚一点,真正重要是响应时间。如果把查询看作是一个任务&#xff0c;那么他由一系列子任务组成&#xff0c;每个子任务都会消耗一定的时间。如果…

Portainer简介及部署

一、介绍 Portainer是Docker的图形化管理工具&#xff0c;提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作&#xff08;包括上传下载镜像&#xff0c;创建容器等操作&#xff09;、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用…

Nexus搭建Maven私有仓库

一、使用Docker安装Nexus 1、查询当前有哪些Nexus镜像 docker search nexus2、下载sonatype/nexus3 docker pull docker.io/sonatype/nexus33、运行nexus容器 mkdir -p /usr/local/nexus3/nexus-data #新建挂载目录 chown -R 200 /usr/local/nexus3/nexus-datadocker run -…

日常问题——VMware下的CentOS7 Ping不通百度

问题描述&#xff1a; 在VMware下新创建的CentOS ping 不通百度 解决方案&#xff1a; 1、点击VMware的编辑按钮下的虚拟网络编辑器 2、更改设置后&#xff0c;选择NAT类型&#xff0c;点击NAT设置 3、记录下&#xff0c;子网ip&#xff0c;掩码&#xff0c;网管IP信息 4、…

CentOS7.6下安装Ambari

一、准备工作 1.1、准备三台CentOS 1.2、配置静态IP、DNS vi /etc/sysconfig/network-scripts/ficfg-ens33IPADDR为 配置的ip NETMASK 子网掩码 GATEWAY 网关 配置保存后重启虚拟网络 service network restart1.3、配置Hostname vi /etc/hostname#将第一行替换成新名字 m…

linux系统启动流程详解

一、MBR的概念 主引导扇区位于硬盘的0磁道0柱面1扇区,共512bytes,可存放一小段程序及主分区表,由三大部分组成: 硬盘主引导记录MBR(Master Boot Record)占446bytes 分区表DPT(Disk Partition Table)占64bytes 硬盘有效标志(Magic Number)占2bytes。 硬盘…

Ambari系统架构

一、Ambari系统架构 Ambari框架采用的是Server/Client的模式&#xff0c;主要由两部分组成&#xff1a;ambari-agent和ambari-server。ambari依赖其它已经成熟的工具&#xff0c;例如其ambari-server 就依赖python&#xff0c;而ambari-agent还同时依赖ruby, puppet&#xff0…

Linux系统的基本安装

一、制作Linux安装启动盘 1.准备一个干净的U盘&#xff0c;格式化。 2.下载64位系统镜像&#xff1a;rhel-server-6.8-x86_64-dvd.iso。64位系统直接安装就好&#xff0c; 3.首先制作一个启动盘&#xff0c;解压rhel-server-6.8-i386-dvd.iso文件 4.下载安装UltraISO&#…

Shell基本概念

一、什么是shell shell是外壳的意思&#xff0c;就是操作系统的外壳。我们可以通过shell命令来操作和控制操作系统&#xff0c;比如Linux中的Shell命令就包括ls、cd、pwd等等。总结来说&#xff0c;Shell是一个命令解释器&#xff0c;它通过接受用户输入的Shell命令来启动、暂…

Linux下Java的安装与配置

0、下载好JDK安装包后上传到Linux服务器的/usr/local/java/下 1、解压tar -zxvf jdk-8u251-linux-x64.tar.gz 2、改名mv jdk1.8.0_251 jdk1.8 3、配置环境变量vi /etc/profile 添加以下内容 #JAVA export JAVA_HOME/usr/local/java/jdk1.8 export JRE_HOME$JAVA_HOME/jre e…

Spark初识-什么是Spark

Spark是一个基于内存的开源计算框架&#xff0c;于2009年诞生于加州大学伯克利分校AMPLab&#xff08;AMP&#xff1a;Algorithms&#xff0c;Machines&#xff0c;People&#xff09;&#xff0c;它最初属于伯克利大学的研究性项目&#xff0c;后来在2010年正式开源&#xff0…

系统优化

1、关闭selinux sed -i ‘s/SELINUXenforcing/SELINUXdisabled’ setenforce 0 2.精简开机服务 ntsysv setup system service

Spark初识-Spark与Hadoop的比较

Spark&#xff0c;是分布式计算平台&#xff0c;是一个用scala语言编写的计算框架&#xff0c;基于内存的快速、通用、可扩展的大数据分析引擎 Hadoop&#xff0c;是分布式管理、存储、计算的生态系统&#xff1b;包括HDFS&#xff08;存储&#xff09;、MapReduce&#xff08;…

Spark初识-Spark基本架构概览使用

当需要处理的数据量超过了单机尺度(比如我们的计算机有4GB的内存&#xff0c;而我们需要处理100GB以上的数据)这时我们可以选择spark集群进行计算&#xff0c;有时我们可能需要处理的数据量并不大&#xff0c;但是计算很复杂&#xff0c;需要大量的时间&#xff0c;这时我们也可…

Spark初识-弹性分布式数据集RDD

Spark 的核心是建立在统一的抽象弹性分布式数据集&#xff08;Resiliennt Distributed Datasets&#xff0c;RDD&#xff09;之上的&#xff0c;这使得 Spark 的各个组件可以无缝地进行集成&#xff0c;能够在同一个应用程序中完成大数据处理。 一、RDD概念 RDD 是 Spark 提供…

Spark入门- Spark运行Local本地模式

一、Spark单机模式部署 Spark版本 &#xff1a; spark-2.4.7-bin-hadoop2.7 1、安装配置JDK环境 2、下载Spark 官网下载http://spark.apache.org/ 然后上传到LInux服务器上 3、解压 tar -zxvf spark-2.4.7-bin-hadoop2.7.tgz解压目录说明 bin 可执行脚本 conf …

Spark入门-了解Spark核心概念

在本文中我们将从Spark集群角度和程序应用的角度来对相关概念进行了解 一. 站在集群角度 1.1 Master Spark 特有资源调度系统的 Leader。掌管着整个集群的资源信息&#xff0c;类似于 Yarn 框架中的 ResourceManager&#xff0c;主要功能&#xff1a; 监听 Worker&#xff0…

Spark运行standalone集群模式

spark的集群主要有三种运行模式standalone、yarn、mesos&#xff0c;其中常被使用的是standalone和yarn&#xff0c;本文了解一下什么是standalone运行模式&#xff0c;并尝试搭建一个standalone集群 一、standalone模式 standalone模式&#xff0c;是spark自己实现的&#xf…