忘了什么原因突然想看下JCF,于是就有了这个阅读体会。 
java版本基于sun jdk1.6.0_18

1 通用接口

public interface Iterable<T> 
public interface Iterator<E> 
一个典型的iterator模式的应用。 
注意注释中提到的Iterator和enumerations一个不同点是方法名的提高,命名还是很重要的。

public interface Collection<E> 
extends Iterable<E>

比较有意思。 
线程策略由实现类决定。 
注意contains并不是一定要使用equals,而是把自由给了实现类。 
很多可选操作。 
如果要继承equals方法需要特别小心,默认的约定是List和Set永远不相等。

Java代码  
  1. // Query Operations
  2. int size();
  3. boolean isEmpty();
  4. boolean contains(Object o);
  5. Iterator<E> iterator();
  6. Object[] toArray();
  7. <T> T[] toArray(T[] a);
  8. // Modification Operations
  9. boolean add(E e);
  10. boolean remove(Object o);
  11. // Bulk Operations
  12. boolean containsAll(Collection<?> c);
  13. boolean addAll(Collection<? extends E> c);
  14. boolean removeAll(Collection<?> c);
  15. boolean retainAll(Collection<?> c);
  16. void clear();
  17. // Comparison and hashing
  18. boolean equals(Object o);
  19. int hashCode();

public abstract class AbstractCollection<E> 
implements Collection<E>

注意对整数加法溢出的处理。 
用简单的算法实现给出了Collection的基本实现。 
最大限度的简化了子类的编写,同时不限制子类效率更高的写法。

public interface Queue<E> 
extends Collection<E>

public interface Deque<E> 
extends Queue<E>

Comparator 
注意consistent with equals的意义,即 
c.compare(e1, e2)==0 <=> e1.equals(e2) 
这里可以重温一下equals和hashcode的关系。 
Comparable

2 Set  
public interface Set<E> 
extends Collection<E> 
为了方便copy了Collection<E>所有的方法。 
明确了Set作为对数学上Set的建模。 
对方法做了更为详尽的注释。如add不能加入重复元素。 
明确了Set的equals和hashCode的契约。 
equals,只有Set和Set才可能相等,size相同,元素相等。 
hashCode,每一个元素hashCode的和,保持了Object的equals和hashCode的惯用法。

public abstract class AbstractSet<E> 
extends AbstractCollection<E> 
implements Set<E> 
Set的骨架类。 
简单实现了equals和hashCode。 
removeAll考虑了使用2个Set中较小的一个做迭代,优化了性能。

Java代码  
  1. public boolean removeAll(Collection<?> c) {
  2. boolean modified = false;
  3. if (size() > c.size()) {
  4. for (Iterator<?> i = c.iterator(); i.hasNext(); )
  5. modified |= remove(i.next());
  6. } else {
  7. for (Iterator<?> i = iterator(); i.hasNext(); ) {
  8. if (c.contains(i.next())) {
  9. i.remove();
  10. modified = true;
  11. }
  12. }
  13. }
  14. return modified;
  15. }

public class HashSet<E>    
extends AbstractSet<E>    
implements Set<E>, Cloneable, java.io.Serializable 
由HashMap作为存储。用key来存储元素,用一个哑元作为所有key对应的value。 
iterator是fail fast的,但是这是一个best effect行为,程序的正确性不应该依赖该异常。 
注意IO序列化的一个自定义实现。writeObject和readObject。 
小技巧: 
HashSet(int initialCapacity, float loadFactor, boolean dummy) 
dummy在这里的作用只是为了和其他的构造函数相区别。 
主要是和public HashSet(int initialCapacity, float loadFactor)区别。

public class LinkedHashSet<E>    
extends HashSet<E>    
implements Set<E>, Cloneable, java.io.Serializable 
使用了LinkedHashMap保持了元素的插入顺序。

public interface SortedSet<E> 
extends Set<E>

public interface NavigableSet<E> 
extends SortedSet<E> 
public class TreeSet<E> 
extends AbstractSet<E> 
implements NavigableSet<E>, Cloneable, java.io.Serializable

和HashSet,LinkedHashSet一样,都是代理到对应的Map来实现。

3 List

public interface List<E> 
extends Collection<E> 
为了方便copy了Collection<E>所有的方法。 
List是有序队列。 
增加了很多List特定的方法。

Java代码  
  1. // Positional Access Operations
  2. E get(int index);
  3. E set(int index, E element);
  4. void add(int index, E element);
  5. E remove(int index);
  6. // Search Operations
  7. int indexOf(Object o);
  8. int lastIndexOf(Object o);
  9. // List Iterators
  10. ListIterator<E> listIterator();
  11. ListIterator<E> listIterator(int index);
  12. // View
  13. List<E> subList(int fromIndex, int toIndex);

public interface ListIterator<E> 
extends Iterator<E> 
基于游标的一个列表的Iterator。 
可以前后移动,可以增加,删除,设置元素。

public abstract class AbstractList<E> 
extends AbstractCollection<E> 
implements List<E> 
随机访问List的骨架类。 
modCount这个字段标识了List结构性被改动的次数,而且子类继承的时候,该字段是一个可选的字段。 
该类中的Itr,ListItr内部类的实现还是很值得一看一学的。 
同样,SubList的实现也是比较简洁的。 
RandomAccessSubList。

public interface RandomAccess 
这个是一个list的marker interface。 
列表相关的算法由于列表的实现不同性能差异太大。

public abstract class AbstractSequentialList<E> 
extends AbstractList<E> 
链表型列表的骨架类。

public class ArrayList<E> 
extends AbstractList<E> 
implements List<E>, RandomAccess, Cloneable, java.io.Serializable 
对System.arraycopy方法的大量使用。 
为了少做一点检查,提高性能,使用fastRemove。 
一般我们都是使用List接口来使用List,直接使用ArrayList可以更好的控制List。当然,没有特殊需求还是使用List比较方便。 
ArrayList中提供了trimToSize,ensureCapacity来对其内部数据结构做一些控制。

public class LinkedList<E> 
extends AbstractSequentialList<E> 
implements List<E>, Deque<E>, Cloneable, java.io.Serializable 
使用了哑元的双向链表。 
Clear时,删除原有所有元素的引用。 
private Entry<E> entry(int index)时不是单向遍历,而是判断正向和逆向哪个方向路径更短,然后决定使用哪个方向查找。 
ListItr.remove() 注意List的ListIterator是双向的,删除的时候要判断前一个动作是什么。

4 Map

public interface Map<K,V> 
interface Entry<K,V>

public abstract class AbstractMap<K,V> 
implements Map<K,V> 
map的骨架类。 
大量实现是基于entrySet。 
JCF中充满了类似于

Java代码  
  1. public V get(Object key) {
  2. Iterator<Entry<K,V>> i = entrySet().iterator();
  3. if (key==null) {
  4. while (i.hasNext()) {
  5. Entry<K,V> e = i.next();
  6. if (e.getKey()==null)
  7. return e.getValue();
  8. }
  9. } else {
  10. while (i.hasNext()) {
  11. Entry<K,V> e = i.next();
  12. if (key.equals(e.getKey()))
  13. return e.getValue();
  14. }
  15. }
  16. return null;
  17. }

的代码,提高性能,避免在每个循环体中比较。

public static class SimpleEntry<K,V> 
implements Entry<K,V>, java.io.Serializable 
public static class SimpleImmutableEntry<K,V> 
implements Entry<K,V>, java.io.Serializable

public class HashMap<K,V> 
    extends AbstractMap<K,V> 
    implements Map<K,V>, Cloneable, Serializable 
关于capacity, load factor, rehash之间的关系。 
HashMap不是线程安全的。大部分JCF的类都不是线程安全的。 
Capacity必须是2的幂。默认16。Loadfactor默认0.75。 
Map初始化的一个钩子函数,方便子类实现。 
对于null的特殊处理,所有key为null的都放在index为0的位置。 
内部类,wrapper用的出神入化。 
用链表法解决hash冲突。

public class LinkedHashMap<K,V> 
    extends HashMap<K,V> 
implements Map<K,V> 
可以是插入顺序,也可以是access order。 
使用双链表保持顺序。

public interface SortedMap<K,V> 
extends Map<K,V>

public interface NavigableMap<K,V> 
extends SortedMap<K,V>

public class TreeMap<K,V> 
extends AbstractMap<K,V> 
implements NavigableMap<K,V>, Cloneable, java.io.Serializable 
底层使用红黑树。 
为了性能,在get时对自然序和comparator的分开处理。

Java代码  
  1. final Entry<K,V> getEntry(Object key) {
  2. // Offload comparator-based version for sake of performance
  3. if (comparator != null)
  4. return getEntryUsingComparator(key);
  5. if (key == null)
  6. throw new NullPointerException();
  7. Comparable<? super K> k = (Comparable<? super K>) key;
  8. Entry<K,V> p = root;
  9. while (p != null) {
  10. int cmp = k.compareTo(p.key);
  11. if (cmp < 0)
  12. p = p.left;
  13. else if (cmp > 0)
  14. p = p.right;
  15. else
  16. return p;
  17. }
  18. return null;
  19. }
  20. final Entry<K,V> getEntryUsingComparator(Object key) {
  21. K k = (K) key;
  22. Comparator<? super K> cpr = comparator;
  23. if (cpr != null) {
  24. Entry<K,V> p = root;
  25. while (p != null) {
  26. int cmp = cpr.compare(k, p.key);
  27. if (cmp < 0)
  28. p = p.left;
  29. else if (cmp > 0)
  30. p = p.right;
  31. else
  32. return p;
  33. }
  34. }
  35. return null;
  36. }

果然还是TreeMap的代码最难读懂。

Java代码  
  1. final Entry<K,V> getCeilingEntry(K key) {
  2. Entry<K,V> p = root;
  3. while (p != null) {
  4. int cmp = compare(key, p.key);
  5. //进入到左子树,说明该子树的root比key大。
  6. if (cmp < 0) {
  7. if (p.left != null)
  8. p = p.left;
  9. else
  10. return p;
  11. } else if (cmp > 0) {
  12. if (p.right != null) {
  13. p = p.right;
  14. } else {
  15. //如果是左子树进来的,查找该左子树的root。如果不是,结果是null。
  16. Entry<K,V> parent = p.parent;
  17. Entry<K,V> ch = p;
  18. while (parent != null && ch == parent.right) {
  19. ch = parent;
  20. parent = parent.parent;
  21. }
  22. return parent;
  23. }
  24. } else
  25. return p;
  26. }
  27. return null;
  28. }

TreeMap可以插入为null的key,但是插入后,该TreeMap基本就不能使用了。

Java代码  
  1. @Test(expected = NullPointerException.class)
  2. public void testAddNullToTreeMap() {
  3. TreeMap<String, String> tm = new TreeMap<String, String>();
  4. tm.put(null, "test");
  5. tm.get("key");
  6. }

View返回的都是快照(SimpleImmutableEntry),无法setValue,但是可以使用map的put方法来改变值。 
红黑树的插入以前一直没有看,现在一看果然精彩。 
注意红黑树删除元素时的特殊处理。

Java代码  
  1. // deleted entries are replaced by their successors
  2. if (lastReturned.left != null && lastReturned.right != null)
  3. next = lastReturned;

最后的构建红黑树也比较有意思,如果一个完全二叉树,最后一层不满的话,则全部为RED。

小结  
1 漂亮的注释:JCF的注释的确是比较漂亮的,简单清晰。唯一的不足就是为了保持每个方法注释的完整性,导致有很多重复的注释。当然,对于使用方法有需要才去看注释的程序员来说,这样更方便一点,但是对于完整阅读代码的人来说,貌似有点多余。 
2 勿以善小而不为:当看到Iterator的类说明中有改善命名一条时,真的有点感动。 
3 大师级的设计和代码复用技术。这个没有什么好说的,喜爱代码的人是在看艺术品。 
4 框架代码对性能的有限度强调:在可以提高性能的地方提高性能,但是并不阻止其他人实现子类时提供性能更好的方法。同时,代码并没有因为对一些性能问题的特殊处理而变得丑陋。 
5 关于类线程安全性的注释:一般代码哪里看的到这个。 
6 几个骨架类的设计和实现都很简洁有力,仅仅使用几个基本方法,就可以实现接口的所有功能。 
7 modCount思想。fail-fast的实现机制。 
8 平时还是要打好基础,数据结构和算法中对红黑数的插入和删除以前没有怎么看过,只知道概念和用途,直接导致看到TreeMap的时候比较费力。 
9 一行行读代码未必是一个好办法,对于JCF的接口和类的体系还是比较熟悉的,因此没有什么问题,但是Map的Iterator和View的继承体系以前没有接触过,看完过自己觉得没有清晰的把握设计思路,动手画画图,真是有如泰山登顶,一览天下的感觉,神清气爽啊。 
10 优秀的源代码还是应该早读的,有点后悔为什么拖到现在才开始看JCF,以前干嘛去了。 
11 强烈推荐大家都看看JCF。

java集合框架类源代码阅读体会相关推荐

  1. java集合框架类_Java集合框架总结—超详细-适合面试

    Set和List接口是Collection接口派生的两个子接口,Queue是Java提供的队列实现,类似于List. Map实现类用于保存具有映射关系的数据(key-value). 2.Set.Lis ...

  2. java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类...

    本文关键词: java集合框架  框架设计理念  容器 继承层级结构 继承图 集合框架中的抽象类  主要的实现类 实现类特性   集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...

  3. Java集合框架之四大接口、常用实现类,java基础面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  4. java集合框架源代码_面试必备——Java集合框架

    Java集合框架面试题 常见集合 集合可以看作是一种容器,用来存储对象信息. 数组和集合的区别: (1)数组长度不可变化而且无法保存具有映射关系的数据:集合类用于保存数量不确定的数据,以及保存具有映射 ...

  5. JavaSE入门学习34:Java集合框架之Collection接口、子接口及其实现类

    一Collection接口 Collection接口定义了存取一组对象的方法,其子接口Set.List和Queen分别定义了存储方式. 使用Collection接口需要注意: 1Collection接 ...

  6. 史上最全的集合框架讲解 ----- Java 集合框架(3)---- Map 相关类最全解析

    引言 好了,步入正题,上篇文章Java 集合框架(2)---- List 相关类解析中我们一起看了一下 List 接口的相关具体类(ArrayList.LinkedList-.),这篇开始我们开始探索 ...

  7. Java 集合框架(5)---- Map 相关类解析(中)

    本文标题大纲: 文章目录 前言 HashMap TreeMap 指定 TreeMap 的元素排序方式 前言 还是先上那张图吧,我又偷懒了,还是只关注 Map 接口下的类就行了: 在上上篇文章中我们一起 ...

  8. java集合框架——接口图+类图+遗留类图

    [0]README 0.1)绝对的干货,理清 java集合框架中类和接口的层次关系:

  9. java list有序还是无序_牛批!2w字的Java集合框架面试题精华集(2020最新版),赶紧收藏。...

    一个多月前,作者和一些小伙伴决定做一系列的 Java 知识点常见重要问题的小册,方便用来夯实基础!小册的标准就一个,那就是:取精华,取重点.每一本小册,我们都会充分关注我们所总结的知识点是否达到这个标 ...

最新文章

  1. R语言ggplot2可视化小提琴图(violin plot)并使用ggsignif添加分组显著性(significance)标签
  2. oracle增加数据时报没安装java_在linux上安装Oracle Developer Tools for VS Code
  3. WPF wpf scrollviewer 触屏滚动 窗体弹跳
  4. 计算机网络系统--Microsoft Lync 与 腾讯通RTX 对比(转载)
  5. SOA与微服务基本原则及对比
  6. python金融量化风险_【手把手教你】Python量化策略风险指标
  7. WordPress中缠结的自定义数据世界
  8. Android应用开发-图片加载库Glide
  9. Ext中namespace的作用
  10. anguarjs 上传图片预览_前端图片上传那些事儿
  11. numpy.linspace()的使用方法
  12. Spring教程笔记8 基于SHH的员工信息管理系统
  13. Apache Wicket 1.5发布
  14. 传奇源码分析-客户端(WindHorn简述和传奇文件格式分析)
  15. 态势感知——活跃IP段探测脚本集合【多语言】
  16. 4月13日云栖精选夜读:雪佛兰和阿里妈妈撒红包雨!到店率增加20%是如何做到的?...
  17. 【产业互联网周报】云厂商加速布局政企市场:华为云发布七款新产品;腾讯政务战略升级;钉钉发布数字区县解决方案...
  18. 电脑提示MSVCP140.dll文件丢失的解决方法
  19. C++提高进阶,你知道多少?
  20. matplotlib 点线动画

热门文章

  1. 【设计模式】状态模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
  2. 【Flutter】Image 组件 ( 内存加载 Placeholder | transparent_image 透明图像插件 )
  3. 【词汇】preci-词根、ap-前缀、de-前缀、ous-后缀、ify-后缀、ise-后缀
  4. 【Android 高性能音频】Oboe 开发流程 ( 检查 Oboe 音频流属性 | 开始播放 | 停止播放 | 关闭 Oboe 音频流 | 重新配置 Oboe 音频流属性 )
  5. 【计算机网络】传输层 : TCP 可靠传输 ( 可靠传输机制 | 快速重传机制 )
  6. 【Android 属性动画】属性动画 Property Animation 简介 ( 属性动画简介 | 属性动画特性 )
  7. Jmeter使用入门
  8. centos7.3安装MongoDB
  9. LAMBDA表达式常用 (全)
  10. 拜读了《婆媳关系好坏取决于老公》一文,看似有道理,细读感觉其实应该不是那么回事...