一点一点看JDK源码(一)Collection体系概览

liuyuhang原创,未经允许进制转载

本文举例使用的是JDK8的API

目录:一点一点看JDK源码(〇)

1.综述

  Collection为集合类,是jdk中最为常用的类了,实际上我并不认同这个东西叫做集合

  我更倾向于叫做容器,当然容器不止有它一种。

  在计算机专业中,大概都会学一门叫做《数据结构》的课程吧

  本质上来说,数据结构,实际上是设计一种容器,而容器的特性大体包括如下:

  • 容器中如何进行存储
  • 容器中的数据如何获取
  • 容器中的数据如何添加  
  • 容器中的数据如何遍历
  • 器中的数据如何搜索
  • 容器中的其他特性(判空,替换,排序,溢出,并发,同步,拆分,汇聚等等)

  在我的眼中,Collection是容器的框架集,其中包含了我们经常使用的容器,

  

2.Collection的关注点

  Collection隶属于java.util包。在本文中不讨论concurrent包或其他派生集合体系,只讨论基础

  从Collection类的原码类注释@see中可看到,集合体系的大概设计中重点关注的如下:

  • Set(接口)
  • List(接口)
  • Map(接口)
  • SortedSet(接口)
  • SortedMap(接口)
  • HashSet(类)
  • TreeSet(类)
  • ArrayList(类)
  • LinkedList(类)
  • Vector(类)
  • Collections(类)
  • Arrays(类)
  • AbstractCollection(抽象类)

  之所以只关注这些,主要有两方面原因:

    ①我们的时间和技术水平有限,不可能完整的看完JDK

    ②JDK中的任何设计都是迭代产生的,我们没有必要看旧版本而不更新的类

  接下来将依照上述内容,从接口底层给它从头扒到尾,虽然说Collection中@see的是这些

  但是关注点肯定不止于此。

3.Collection剖析

  先上Collection源码,去掉原doc注释,我想写的内容直接写在贴出来的代码中作为注释了。

 public interface Collection<E> extends Iterable<E> {
// Query Operations 原注释,不明意义 //定义size方法,应返回size大小,最大值为Integer.MAX_VALUE
int size(); //定义isEmpty方法,用于返回是否为空
boolean isEmpty(); //定义contains方法,判断一个obj是否属于此集合
boolean contains(Object o); //定义迭代器方法,返回一个迭代器对象
Iterator<E> iterator(); //定义转换为转换Obj数组的方法,返回一个obj数组
Object[] toArray(); //定义转换为泛型T数组的方法,返回一个指定泛型的数组
<T> T[] toArray(T[] a); //定义add方法,添加一个元素e,并返回添加成功标志
boolean add(E e); //定义remove方法,移除一个元素obj,并返回移除元素成功标志
boolean remove(Object o); //定义containsAll方法,判断是否包含集合实例对象c
boolean containsAll(Collection<?> c); //定义addAll方法,添加集合实例对象c到本实例中
boolean addAll(Collection<? extends E> c); //定义removeAll方法,从本实例中移除集合实力对象c
boolean removeAll(Collection<?> c); /**
* jdk8新增
* 大意为:
* 定义removeIf方法,该方传递参数为函数式,传递内容是一个接口类型,该接口类型
* 定义为一个filter函数,该函数用于传递给Objects.requireNonNull判断,然后调用
* 迭代器,将满足该定义的filter的本实例中的元素移除
* @since 1.8
*/
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
} //定义retainAll方法,取本例与集合实例c的交集,判断交集元素数量是否大于0
boolean retainAll(Collection<?> c); //定义clear方法,清除本例集合中的所有元素
void clear(); // Comparison and hashing 原注释,不明意义 //不解释
boolean equals(Object o); //定义hashCode方法,获取hashCode标记的方法
int hashCode(); /**
*jdk8新增
*大意为:
*将迭代器拆分,重写自Iterable接口,从已知元素数量的本例中返回拆分后的迭代器
*此方法返回的为本类本身
*子类可能重写迭代器拆分,将一个集合的迭代拆分为多个集合的迭代交由多个线程
* @since 1.8
*/
@Override//重写父类
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
} /**
* jdk8新增
* 大意为:
* 将默认的迭代器拆分后的结果,聚合为流,该流并非io中的流,
* 是一种类似于数据排序操作流
* @since 1.8
*/
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
} /**
* jdk8新增
* 同上,但是具体其他的实现中,因为可并行,所以可能是线程不安全的
*
* @since 1.8
*/
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}

  以上代码对Collection接口中的方法进行了简单的解释,同时对java8新增的一些方法也进行了简单的解释。

  因为定义的都是接口,实际实现的方法非常的少,

  而应java8多线程的特性提供的一些default方法也有子类去实现。

  在堆Collection接口中的源码进行了解的同时,不要忘记此接口继承了Iterable接口。

  因此Iterable接口也必定要看一下的,内容比较少,但是通过源码的剖析,发现了集合类的共性:

  集合作为容器,其体系中的所有集合都包括了:

  大小(size),判空(isEmpty),添加元素(add),删除元素(remove),是否包含(contains)

  转换数组(toArray),清空(clear),遍历与迭代(forEach(父接口中),iterator)

  是否相同(equals),哈希(hashCode),求交集(retainAll)

  除此之外,提供了java8的分离接口,聚合接口,为了大容量集合的多线程操作

  注意,Collection接口并没有重写父接口的forEach方法,而iterator方法虽然有出现,但是没有@Override注解

  同样贴一下代码,同样的去掉原doc注释,我想写的内容直接写在贴出来的代码中作为注释了。

 public interface Iterable<T> {

     //定义iterator方法,返回迭代器
Iterator<T> iterator(); /**
* jdk8新增
* 大意为:
* 根据action调用Objects.requireNonNull进行过滤
* 过滤结果调用for循环取出,
* @since 1.8
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
} /**
* jdk8新增
* 大意为:
* 分离迭代器,将未知大小的迭代器进行拆分,返回拆分的迭代器本身
*
* @since 1.8
*/
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}

有时候我们并不怎么关心父接口的问题,但是实际上这个问题有点重要的还是,上两张图解释一下:

 不要以为以上两种接口定义实现类的方式没区别,实际上有区别,区别大了,可实现的方法列表有差异

该问题具体解析,将在后续更新中详细写代码测试。

Collection接口内容较少,多数都只是定义了必要内容,具体实现较少。难点都在java8中的default方法上了

等以后弄彻底明白了可能再写通俗解释和常用方式。

明天更对于List接口的剖析和ArrayList的简要剖析!

以上!

一点一点看JDK源码(一)Collection体系概览的更多相关文章

  1. 一点一点看JDK源码(〇)

    一点一点看JDK源码(〇) liuyuhang原创,未经允许进制转载 写在前面: 几乎所有的大神都会强调看源码,也强调源码的重要性: 但是如何看源码,源码看什么?看了什么用?看了怎么用? 困扰很多人, ...

  2. 一点一点看JDK源码(二)java.util.List

    一点一点看JDK源码(二)java.util.List liuyuhang原创,未经允许进制转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 List译为表,一览表, ...

  3. 一点一点看JDK源码(三)java.util.ArrayList 前偏

    一点一点看JDK源码(三)java.util.ArrayList liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 ArrayLi ...

  4. 一点一点看JDK源码(四)java.util.ArrayList 中篇

    一点一点看JDK源码(四)java.util.ArrayList 中篇 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 在前篇中 ...

  5. 一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach

    一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 代 ...

  6. 一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator

    一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JD ...

  7. 一点一点看JDK源码(五)java.util.ArrayList 后篇之SubList

    一点一点看JDK源码(五)java.util.ArrayList 后篇之SubList liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) S ...

  8. 一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历

    一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看J ...

  9. 一点一点看JDK源码(五)java.util.ArrayList 后篇之removeIf与Predicate

    一点一点看JDK源码(五)java.util.ArrayList 后篇之removeIf与Predicate liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点 ...

随机推荐

  1. sql: TRIGGER

    --Common Table Expressions(CTE) WITH HighSample (SampleId,SampleTitle,SampleContent) AS ( SELECT Sam ...

  2. 远程连接Redis服务器

    建立了一个redis服务器,那么其他主机应该怎么连接上呢? /** * * 修改redis.conf配置文件 * */ // 1. 注释掉bind绑定配置 // 2. 搜索并修改为 protected ...

  3. linux 下解决git clone报错

    解决报错:error: The requested URL returned error: 401 Unauthorized while accessing   问题报错:error: The req ...

  4. 关于zepto 选择特定值的input 报错问题

    zepto 选择特定值的input  时,需要用单引号或双引号引用这个特定值 否则 报错

  5. c# BackGroundWorker 多线程操作的小例子 (转)

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...

  6. Suse LAMP setup

    This page will describe the steps you have to take to install LAMP, which stands for Linux Apache Ma ...

  7. RuntimeBroker ClipboardBroker EoP

    datetime: 2017.04.28 漏洞简介 随着沙箱技术的普及,现在主流的操作系统及软件都开始支持沙箱,以此来缓解层出不穷的远程代码执行漏洞对系统造成的危害.AppContainer是自Win ...

  8. C++ int与string的相互转换(含源码实现)

    一.int转换成string Ⅰ.to_string函数 c++11标准增加了全局函数std::to_string: string to_string (int val); string to_str ...

  9. 科普文:从人人网看网络科学(Network Science)的X个经典问题

    转:https://zr9558.wordpress.com/2013/12/05/科普文:从人人网看网络科学(network-science)的x个经典问/ 长文,写了N个小时写完的.你肯定能看懂, ...

  10. 全新Chrome Devtool Performance使用指南

    运行时性能表现(runtime performance)指的是当你的页面在浏览器运行时的性能表现,而不是在下载页面的时候的表现.这篇指南将会告诉你怎么用Chrome DevToos Performan ...