JDK源代码阅读笔记(一)------容器篇

一、类图


二、基本抽象基类
1.Collection
所有List和Set都需要实现的基本接口

2.AbstractCollection
此类提供 Collection 接口的骨干实现,以最大限度地减少了实现此接口所需的工作
用迭代器对数据进行访问(不是随机访问)

3.AbstractList
此类提供 List 接口的骨干实现,以最大限度地减少实现“随机访问”数据存储(如数组)支持的该接口所需的工作
用迭代器对数据进行访问(不是随机访问)

4.AbstractSet
此类提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作
用迭代器对数据进行访问(不是随机访问)

5.AbstractSequentialList
此类提供了 List 接口的骨干实现,从而最大限度地减少了实现受“连续访问”数据存储(如链接列表)支持的此接口所需的工作( 用迭代器对数据进行访问,不是随机访问)

6.AbstractSet
此类提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。
用迭代器对数据进行访问,不是随机访问)

7.AbstractMap
此类提供 Map 接口的骨干实现,以最大限度地减少实现此接口所需的工作
用迭代器对数据进行访问,不是随机访问)


三、List

List可以将元素维护在特定的序列中,并且允许一个相同元素在集合中多次出现。List接口在Collection接口的基础上增加了大量的方法,使得可以在List中间插入和移除元素。

Abstract类之外,在学习中比较常用的类有ArrayList(基于数组实现),LinkedList(基于循环链表实现)Vector(基于数组实现,线程安全),Stack(是Vector的子类,基于数组实现)

1.ArrayList
继承自AbstractList,实现List等接口,基本属性如下:

public  class  ArrayList<E>  extends  AbstractList<E>
         implements  List<E>, RandomAccess, Cloneable, java.io.Serializable
{
     private  static  final  long  serialVersionUID  = 8683452581122892189L;

     /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer.
     */
     private  transient  Object[]  elementData ;

     /**
     * The size of the ArrayList (the number of elements it contains).
     *
     *  @serial
     */
     private  int  size ;‘
}

基本数据存在名为elementData的数组中,查询指定元素和遍历整个元素都是对数组进行操作
对于ArrayList的增加与删除,利用了Arrays工具类进行数组复制,Arrays的最终实现是利用如下语句

System.arraycopy(original, 0, copy, 0, Math.min(original. length , newLength));

该语句会编译成本地代码,提高效率

2.Vector
实现大体和ArrayList一样,只是每个方法上加了同步标志

3.Stack
继承于Vector,一个栈,限制客户端代码操作数组的位置,只能在栈顶,具体实现时即是数组最后一个元素的位置

4.LinkedList
继承自AbstractSequentialList( 用迭代器对数据进行访问,不是随机访问)
实现的是一个双链表,所有操作都是按照双重链接列表的需要执行的,基本属性如下:

public  class  LinkedList<E>  extends  AbstractSequentialList<E>
     implements  List<E>, Deque<E>, Cloneable, java.io.Serializable
{
     private  transient  Entry<E>  header  =  new  Entry<E>( null ,  null ,  null );
     private  transient  int  size  = 0;

     /**
     * Constructs an empty list.
     */
     public  LinkedList() {
         header . next  =  header . previous  =  header ;
    }
}

header为头节点,size记录链表长度

其中Entry<E>是一个内部类,作为链表的一个节点:
private  static  class  Entry<E> {
      E element;
      Entry<E> next;
      Entry<E> previous;

      Entry(E element, Entry<E> next, Entry<E> previous) {
           this .element = element;
           this .next = next;
           this .previous = previous;
      }
    }

虽然LinkedList获取指定位置的元素时较ArrayList按索引获取较慢,但是JDK中对get方法做了优化:
private  Entry<E> entry( int  index) {
         if  (index < 0 || index >=  size )
             throw  new  IndexOutOfBoundsException( "Index: " + index +  ", Size: " + size );

        Entry<E> e =  header ;
         if  (index < ( size  >> 1)) {
             for  ( int  i = 0; i <= index; i++)
                e = e. next ;
        }  else  {
             for  ( int  i =  size ; i > index; i--)
                e = e. previous ;
        }
         return  e;
    }


四、Set
包括HashSet(无序不重复),LinkedHashSet(按放入顺序有序不重复),TreeSet(按红黑树方式有序不重复)

1.HashSet
利用hash值来查找容器类的元素,因为容器中没个元素的值不相同,所以可以根据元素值来生成hash码

其基本属性如下:

public  class  HashSet<E>  extends  AbstractSet<E>
     implements  Set<E>, Cloneable, java.io.Serializable
{
     static  final  long  serialVersionUID  = -5024744406713321676L;

     private  transient  HashMap<E,Object>  map ;

     // Dummy value to associate with an Object in the backing Map
     private  static  final  Object  PRESENT  =  new  Object();
}

map中的键值“E”用来存储HasgSet中元素值,对应的“Object”固定用PRESENT来表示

其实现基础就是HashMap,所以,HashSet不像List那样可以“随机”访问,只能用迭代器访问

2.TreeSet

其实现基础就是TreeMap,其基本属性如下:

public  class  TreeSet<E>  extends  AbstractSet<E>
     implements  NavigableSet<E>, Cloneable, java.io.Serializable
{
     /**
     * The backing map.
     */
     private  transient  NavigableMap<E,Object>  m ;

     // Dummy value to associate with an Object in the backing Map
     private  static  final  Object  PRESENT  =  new  Object();
}

3.LinkedHashSet
继承于HashSet,其基本属性如下:

public  class  LinkedHashSet<E>  extends  HashSet<E>
     implements  Set<E>, Cloneable, java.io.Serializable {

     private  static  final  long  serialVersionUID = -2851667679971038690L;
}


五、Map

包括HashMap(key无序不重复),LinkedHashMap(key按放入顺序有序不重复),TreeMap(key按红黑树方式有序不重复)

1.HashMap
利用每个key值生成散列值,根据散列值进行数据查找
下图是使用链表来解决散列过程中的碰撞问题,新元素插入链表头


在HashSet中有个loadFactor(负载因子),对于上图所示总共有11个位置,目前有4个位置已经存放,即40%的空间已被使用。在HashSet的默认实现中,初始容量为16,负载因子为0.75,也就是说当有75%的空间已被使用,将会进行一次再散列(再哈希),之前的散列表(数组)将被删除,新增加的散列表是之前散列表长度的2倍,最大值为Integer.MAX_VALUE。

其基本属性如下:

public  class  HashMap<K,V>  extends  AbstractMap<K,V>
     implements  Map<K,V>, Cloneable, Serializable
{

     /**
     * The default initial capacity  -  MUST be a power of two.
     */
     static  final  int  DEFAULT_INITIAL_CAPACITY = 16;

     /**
     * The maximum capacity, used if a higher value is implicitly specified
     * by either of the constructors with arguments.
     * MUST be a power of two <= 1<<30.
     */
     static  final  int  MAXIMUM_CAPACITY = 1 << 30;

     /**
     * The load factor used when none specified in constructor.
     */
     static  final  float  DEFAULT_LOAD_FACTOR = 0.75f;

     /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
     transient  Entry[] table;

     /**
     * The number of key - value mappings contained in this map.
     */
     transient  int  size;

     /**
     * The next size value at which to resize (capacity * load factor).
     *  @serial
     */
     int  threshold;

     /**
     * The load factor for the hash table.
     *
     *  @serial
     */
     final  float  loadFactor;
}

其中Entry[] table是用来存放value的数组,数组下标根据key的散列值生成,Entry的基本实现如下:

static class Entry<K,V> implements Map.Entry<K,V> {
         final  K key;
        V value;
        Entry<K,V> next;
         final  int  hash;
}

其中 “Entry<K,V> next” 保存为该的下一个节点
每次查找先找到table中的一个节点,然后以该节点作为头节点进行链表的遍历

2.TreeMap
key按红黑树方式有序的放入TreeMap,其基本属性如下:

public   class  TreeMap<K,V>  extends  AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
     /**
     * The comparator used to maintain order in this tree map, or
     * null if it uses the natural ordering of its keys.
     *
     *  @serial
     */
     private  final  Comparator<?  super  K> comparator;

     private  transient  Entry<K,V> root =  null ;

     /**
     * The number of entries in the tree
     */
     private  transient  int  size = 0;
}

其中comparator用来比较key值的大小,root作为整棵树的根节点,Entry为每个节点,其属性如下:

     static  final  class  Entry<K,V>  implements  Map.Entry<K,V> {
        K  key ;
        V  value ;
        Entry<K,V>  left  =  null ;
        Entry<K,V>  right  =  null ;
        Entry<K,V>  parent ;
         boolean  color  =  BLACK ;
}

3.LinkedHashMap

继承与HashMap,新加入一个元素时,需要维护hash表和双链表这两个表,以保证既能利用hash来快速查找数据,又能按map中输入数据的顺序输出数据,如果在映射中重新插入 键,则插入顺序不受影响,基本属性如下:

public  class  LinkedHashMap<K,V>  extends  HashMap<K,V>  implements  Map<K,V>
{
     private  static  final  long  serialVersionUID = 3801124242820219131L;

     /**
     * The head of the doubly linked list.
     */
     private  transient  Entry<K,V> header;

     /**
     * The iteration ordering method for this linked hash map: 
       <tt> true </tt>  for access - order,
     *   <tt> false </tt>  for insertion - order.
     *  @serial
     */
     private  final  boolean  accessOrder;
}

其中header代表双链表的头节点,accessOrder用来选择输出的顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值