集合框架源码分析

    科技2024-01-08  101

    1. Java集合总体框架

    Java集合中List,Set以及Map等集合体系详解 Java 集合系列01之 总体框架

    Java集合工具包在java.util.*下,他们的继承关系如下图所示 Java集合主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections)

    List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口Set下有HashSet,LinkedHashSet,TreeSetList下有ArrayList,Vector,LinkedListMap下有Hashtable,LinkedHashMap,HashMap,TreeMapCollection接口下还有个Queue接口,有PriorityQueue类

    1.1 Collection接口

    通过他的注释我们可以知道很多信息 Collection是一个接口,是高度抽象出来的集合,包含了集合的基本操作和属性 Collection包含了List和Set两大分支

    List是一个有序的队列,每一个元素都有它的索引,第一个元素的索引值是0,List的实现类有LinkedList, ArrayList, Vector, Stack。

    Set是一个不允许有重复元素的集合,Set的实现类有HastSet和TreeSet。HashSet依赖于HashMap,它实际上是通过HashMap实现的;TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的

    1⃣️ List接口

    Java 集合框架中最常使用的几种 List 实现类是 ArrayList,LinkedList 和 Vector。

    在各种 List 中,最好的做法是以 ArrayList 作为默认选择。 当插入、删除频繁时,使用 LinkedList; (因为LinkedList底层是用链表实现的,而ArrayList底层是数组) Vector 总是比 ArrayList 慢,所以要尽量避免使用它 (因为实现了同步控制)

    在List中除了继承Collection中的一些方法,还提供了以下操作 ① 位置相关:List 和 数组一样,都是从 0 开始,我们可以根据元素在 list 中的位置进行操作,比如说 get, set, add, addAll, remove;

    ② 搜索:从 list 中查找某个对象的位置,比如 indexOf, lastIndexOf;

    ③ 迭代:使用 Iterator 的拓展版迭代器 ListIterator 进行迭代操作;

    ④ 范围性操作:使用 subList 方法对 list 进行任意范围的操作

    其中在List接口中定以了 ListIterator listIterator()方法用来返回一个listIterator(),listIterator()更强大它可以双向遍历,同时还允许进行add,set,remove等操作

    2⃣️ AbstractCollection抽象类

    AbstractCollection是对Collection接口的直接实现类(是一个抽象类),Collection下的大多数子类都要继承AbstractCollection,他实现了一些方法,也定义了一些抽象方法留给子类实现

    注意: 在AbstractCollection中不支持添加单个元素,所以直接调用add(E)方法会报错,如果子类是可添加的数据结构,需要自己实现这些方法

    public boolean add(E object) { throw new UnsupportedOperationException(); }

    这样设计主要是因为如果你想修改一个不可变的集合时,抛出 UnsupportedOperationException 是标准的行为,比如 当你用 Collections.unmodifiableXXX() 方法对某个集合进行处理后,再调用这个集合的 修改方法(add,remove,set…),都会报这个错

    3⃣️ AbstractList抽象类

    AbstractList 继承自 AbstractCollection 抽象类,实现了 List 接口 ,是 ArrayList 和 AbstractSequentiaList 的父类。它实现了 List 的一些位置相关操作,是第一个实现随机访问方法的集合类,但不支持添加和替换。还是默认不支持add(),set(),remove()操作

    在AbstractList 中实现了ListIterator和Iterator

    4⃣️ Queue接口

    Queue接口与List、Set同一级别,都是继承了Collection接口。 看图你会发现,LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用

    5⃣️ ArrayList/ Vector/ LinkedList

    ArrayList 优点: 底层数据结构是数组,查询快,增删慢。 缺点: 线程不安全,效率高

    Vector 优点: 底层数据结构是数组,查询快,增删慢。 缺点: 线程安全,效率低

    LinkedList 优点: 底层数据结构是链表,查询慢,增删快。 缺点: 线程不安全,效率高

    1.2 Map接口

    Map是一个映射接口,即key-value键值对。Map中的每一个元素包含“一个key”和“key对应的value”。

    AbstractMap是个抽象类,它实现了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是继承于AbstractMap

    TreeMap是有序的,HashMap和HashTable是无序的。Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。

    这就意味着:

    Hashtable是线程安全的,HashMap不是线程安全的。HashMap效率较高,Hashtable效率较低。如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。 查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。Hashtable不允许null值,HashMap允许null值(key和value都允许)父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap

    1.3 Iterable接口

    Collection 继承了 Iterable< E > 接口,Iterable 接口内只有一个 iterator 方法,返回一个 Iterator 迭代器

    1.4 Iterator接口

    它是遍历集合的工具,即我们通常通过Iterator迭代器来遍历集合。我们说Collection依赖于Iterator,是因为Collection的实现类都要实现iterator()函数,返回一个Iterator对象。

    通过Iterable定义的iterator()方法可以拿到iterator对象

    同时foreach遍历集合的底层也是通过迭代器实现的,所以迭代器可以说是集合中必不可少的一部分了

    2. 源码分析

    2.1 为什么要阅读源码

    2.2 如何阅读源码

    掌握用法看继承结构看构造方法看常用方法

    2.3 学习目录

    ArrayList源码分析 Arrays.asList分析 LinkedList源码分析 CopyOnWriteArrayList源码分析 PriorityQueue源码分析 迭代器详解 Map详解 HashMap源码分析 HashMap的几个难点 LinkedHashMap源码分析 ConcurrentHashMap & HashTable

    Processed: 0.012, SQL: 8