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)

JDK源码解析之java.util.AbstractCollection相关推荐

  1. JDK源码解析之Java.util.Collections

    java.util.Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,就像一个工具类,服务于Java的Collection框架. 一.源码解析 1.不可实例 ...

  2. JDK源码解析之Java.util.Collection

    Collection是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素,JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现 一.源码解析 1 ...

  3. JDK源码解析之java.util.ListIterator

    ListIterator是一个功能更加强大的迭代器接口, 它继承于Iterator接口,只能用于各种List类型的访问.可以通过调用listIterator()方法产生一个指向List开始处的List ...

  4. JDK源码解析之java.util.Iterator和java.lang.Iterable

    在Java中,我们可以对List集合进行如下几种方式的遍历:第一种就是普通的for循环,第二种为迭代器遍历,第三种是for each循环.后面两种方式涉及到Java中的iterator和iterabl ...

  5. JDK源码解析之 Java.lang.Compiler

    Compiler类提供支持Java到本机代码编译器和相关服务.在设计上,它作为一个占位符在JIT编译器实现. 一.源码部分 public final class Compiler {private C ...

  6. JDK源码解析之 java.lang.Exception

    异常.是所有异常的基类,用于标识一般的程序运行问题.这些问题通常描述一些会被应用程序捕获的反常情况. 一.源码部分 //继承了java.lang.Throwable public class Exce ...

  7. JDK源码解析之 java.lang.Error

    java.lang.Error 错误.是所有错误的基类,用于标识严重的程序运行问题.这些问题通常描述一些不应被应用程序捕获的反常情况. 一.源码部分 //继承了java.lang.Throwable ...

  8. JDK源码解析之 java.lang.Thread

    位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知识:线程的几种状态.上下文切换 ...

  9. JDK源码解析之 java.lang.Integer

    teger 基本数据类型int 的包装类 Integer 类型的对象包含一个 int 类型的字段 一.类定义 public final class Integer extends Number imp ...

最新文章

  1. iOS 图片渲染及优化
  2. 调试兼容性该注意的的点
  3. javaweb学习总结(二十三):jsp自定义标签开发入门
  4. RUNOOB python练习题 39 数组排序
  5. 【转】职业生涯30年的规划(经典)
  6. 数据3分钟丨Oracle Database 21c终于发布而22c可能直接跳过;2021 OceanBase数据库大赛开启。...
  7. c语言程序2048_C语言2048小游戏演示和说明
  8. 不使用ArcObjects直接查找SDE数据库信息
  9. 百练(九~十二)题解
  10. android studio 融云,融云 SDK 集成详解 – Android Studio
  11. USB C口5V输入,四节串联锂电池充电管理芯片,IC电路板PW4405芯片-22号电路板
  12. 紫书刷题记录:UVa1594,Ducci序列;
  13. layui在IE浏览器刷table刷新数据未更新
  14. 菜鸟的mongoDB学习---(二)MongoDB 数据库,对象,集合
  15. 【ARM-Linux开发】【DSP开发】AM5728介绍
  16. 苹果的破局几招:修漏洞、降价、官方认证翻新机……
  17. 《Hud 2589》Phalanx详解
  18. python有趣小程序春节祝福-用python实现新年祝福微信的自动回复
  19. 安装SQL Server2012时,Windows Installer无法访问的问题
  20. python+tkinter创作老黄历,窗口化显示:择吉,五行,财福喜神

热门文章

  1. php mysql5.7.110安装教程_MYSQL教程mysql5.7.19 winx64安装配置方法图文教程(win10)
  2. mysql range用法_MySQL中Explain的用法总结(详细)
  3. qt窗口左上角坐标变动函数使用中的误区
  4. Python super 函数 - Python零基础入门教程
  5. Python 字典推导式 - Python零基础入门教程
  6. java 不支持fork,grails不能运行fork模式解决方法
  7. java趣事_【趣事】Java程序员最年轻,C++程序员最年老
  8. mysql执行存储过程提示out of_PHP执行MYSQL存储过程报错:Commands out of sync; you can't run...
  9. java调用c jni_Java调用C JNI
  10. python调用node_在node中执行python脚本