简介

   AbstractCollection是一个抽象类,它实现了Collection中除了iterator()和size()之外的所有方法。AbstractCollection的主要作用是方便其他类实现Collection.,比如ArrayList、LinkedList等。它们想要实现Collection接口,通过集成AbstractCollection就已经实现大部分方法了,再实现一下iterator()和size()即可。

方法如下:

  public abstract Iterator<E> iterator();

  public abstract int size(); 

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

  public boolean contains(Object o) { } 

public boolean contains(Object o) {
Iterator<E> it = iterator(); /* 获得 Iterator 对象 */
if (o == null) { /* o 为 null */
while (it.hasNext()) /* 遍历是否含有 null */
if (it.next() == null)
return true;
} else { /* o 不为 null(是某个对象) */
while (it.hasNext()) /* 遍历并按照 equals() 方法比较 */
if (o.equals(it.next()))
return true;
}
return false;
}

  public Object[] toArray() { } 

public Object[] toArray() {
Object[] r = new Object[size()]; /* 根据 collection 大小 new 一个数组 */
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) { /* 遍历实例化的数组 */
/* 下面这个判断为 true 的时机是: */
/* 多线程情况下,collection 数量在遍历过程中减少,提前终止 */
if (! it.hasNext())
return Arrays.copyOf(r, i); /* 返回一个新数组 */
r[i] = it.next();
}
/* List 数量在遍历过程中增加,则返回 */
return it.hasNext() ? finishToArray(r, it) : r;
}

  public <T> T[] toArray(T[] a) {}

public <T> T[] toArray(T[] a) {
int size = size();
T[] r = a.length >= size ? a : /* 如果 a 的长度大于 size,直接使用 a */
(T[])java.lang.reflect.Array /* 如果 a 长度过小,new 一个新数组 */
.newInstance(a.getClass().getComponentType(), size);
Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { /* 遍历 */
/* 下面这个判断为 true 的时机是: */
/* 多线程情况下,collection 数量在遍历过程中减少,提前终止 */
if (! it.hasNext()) {
/* (a == r) => (a.length >= size) */
if (a == r) { /* a.length 本来就足够容纳 collection */
r[i] = null; /* 在结束处写入 null */
} else if (a.length < i) { /* 入参 a 的 length 太小,甚至无法容纳元素减少之后的 collection */
return Arrays.copyOf(r, i); /* 进行拷贝,返回一个新数组 */
} else { /* a.length 遍历前是不够大的,但是由于元素的减少量过多,目前又足够了,无需扩容了 */
System.arraycopy(r, 0, a, 0, i); /* 数值拷贝 */
if (a.length > i) { /* 如果有可能,末尾设置一个 null */
a[i] = null;
}
}
return a;
}
r[i] = (T)it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}

  private static <T> T[] finishToArray(T[] r, Iterator<?> it) {}

  private static int hugeCapacity(int minCapacity) {}

  当迭代器返回比预期更多的元素时,重新分配toArray中使用的数组,并从迭代器完成填充。其实就是扩容,数组长度不够,增加长度

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 code
if (newCap - MAX_ARRAY_SIZE > 0) //如果数组长度大于最大允许数组长度,则通过hugeCapacity方法重新获取一个合适的数组长度
newCap = hugeCapacity(cap + 1); //获取新的数组长度
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
}
// trim if overallocated
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
  //返回新数组的长度
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError
("Required array size too large");
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

  public boolean add(E e){ throw new UnsupportedOperationException(); } //AbstractCollection没有具体实现,调用抛出异常

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

  public boolean containsAll(Collection<?> c) {}  //循环调用contain()方法。

  public boolean addAll(Collection<? extends E> c) {} // 循环添加

  public boolean removeAll(Collection<?> c) {} //循环删除指定集合

  public boolean retainAll(Collection<?> c) {} //循环删除不在集合c中的元素

  public void clear() {} //全部删除

java源码 -- AbstractCollection抽象类的更多相关文章

  1. 自己动手实现springboot运行时执行java源码(运行时编译、加载、注册bean、调用)

    看来断点.单步调试还不够硬核,根本没多少人看,这次再来个硬核的.依然是由于apaas平台越来越流行了,如果apaas平台选择了java语言作为平台内的业务代码,那么不仅仅面临着IDE外的断点.单步调试 ...

  2. 如何阅读Java源码 阅读java的真实体会

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心.   说到技术基础,我打个比 ...

  3. Android反编译(一)之反编译JAVA源码

    Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具  dex2jar   http://code.go ...

  4. 如何阅读Java源码

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...

  5. Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库

    http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...

  6. Programming a Spider in Java 源码帖

    Programming a Spider in Java 源码帖 Listing 1: Finding the bad links (CheckLinks.java) import java.awt. ...

  7. 解密随机数生成器(二)——从java源码看线性同余算法

    Random Java中的Random类生成的是伪随机数,使用的是48-bit的种子,然后调用一个linear congruential formula线性同余方程(Donald Knuth的编程艺术 ...

  8. Java--Eclipse关联Java源码

    打开Eclipse,Window->Preferences->Java 点Edit按钮后弹出: 点Source Attachment后弹出: 选择Java安装路径下的src.zip文件即可 ...

  9. 使用JDT.AST解析java源码

    在做java源码的静态代码审计时,最基础的就是对java文件进行解析,从而获取到此java文件的相关信息: 在java文件中所存在的东西很多,很复杂,难以用相关的正则表达式去一一匹配.但是,eclip ...

随机推荐

  1. 二分算法题目训练(二)——Exams详解

    CodeForces732D——Exams 详解 Exam 题目描述(google翻译) Vasiliy的考试期限将持续n天.他必须通过m门科目的考试.受试者编号为1至m. 大约每天我们都知道当天可以 ...

  2. gulp4配置多页面项目编译打包

    又开始公司的新项目了... 那当我们拿到公司新项目的时候我们需要做些什么呢? 下面就来分享一下我的工作步骤吧(仅使用于初学者,大神勿见怪- -,有不好的地方希望指出,十分感谢) 1. 整版浏览 这是一 ...

  3. ICEM-圆锥的一种画法

    原视频下载地址:https://yunpan.cn/cqK53dKBnduM9  访问密码 42be ​

  4. phpstorm有红波浪线,怎么找到语法错误的地方

    在phpstorm里面,有时候不小心多打了个字符,会导致IDE显示红色波浪线,提示有语法错误了,但是不容易找出在哪一行. 在有红色波浪线的文件上,右键[inspect code]: 检查代码后就会知道 ...

  5. Qt代码配色VS2015风格

    通过本文的方法可以将VS2015的深色主题界面应用到Qt上,对于喜欢VS代码风格配色的人应该会比较有用 效果图:  1. 设置IDE主题 为了配合vs深色的代码编辑背景,将Qt的主题也换成深色版本 2 ...

  6. python 设计模式之 (Chain of Responsibility)责任链模式

    #写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...

  7. Android插件化(五):OpenAtlasの四大组件的Hack

    Android插件化(五):OpenAtlasの四大组件的Hack   转 https://www.300168.com/yidong/show-2776.html 核心提示:引言到目前为止,我们已经 ...

  8. 严重性 代码 说明 项目 文件 行 禁止显示状态错误 C1128 节数超过对象文件格式限制: 请使用 /bigobj 进行编译。

    严重性 代码 说明 项目 文件 行 禁止显示状态错误 C1128 节数超过对象文件格式限制: 请使用 /bigobj 进行编译. 默认情况下,对象文件最多可存放 65,536 (2^16) 个可寻址的 ...

  9. Qt KDChart编译

    最近开发中需要用到甘特图,感觉KDChart这个插件不错,在这里记录一下编译过程(其实很好编译,而且一次性就过了) 下载,kdchart-2.6.1-source,解压 打开src目录,用Qt Cre ...

  10. python调用HTMLTestRunner+unittest实现一次执行多个测试类,并生成与每个测试类对应的测试报告,具体看代码,附上整个project代码

    python自动化框架雏形,根据自己需要封装:ui自动化,接口自动化均可适用,python版本为python3.x,不要问我为什么不用python2.x,附上整个project代码:http://fi ...