JDK源代码阅读笔记(一)------容器篇
来源:互联网 发布:seo www.urkeji.com 编辑:程序博客网 时间:2024/05/17 08:17
一、类图
二、基本抽象基类
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用来选择输出的顺序
- JDK源代码阅读笔记(一)------容器篇
- flask源代码阅读笔记(一)
- z4root源代码阅读笔记一
- Mantle源代码阅读笔记 一
- Mysql源代码阅读笔记(一) 代码流程
- Mysql源代码阅读笔记(一) 命令行参数
- JDK 1.7源码阅读笔记(一)String,StringBuilder,StringBuffer
- JDK源代码阅读:HashMap
- Robot Framework 源代码阅读笔记 之 一
- JDK 源码阅读笔记(一)--OutputStream
- qlwm源代码阅读(一)
- JDK源代码阅读之CharSequence
- 阅读笔记(一)
- Spring源代码解析(一):IOC容器
- Spring源代码解析(一):IOC容器
- Spring源代码解析(一):IOC容器
- Spring源代码解析(一):IOC容器
- Spring源代码解析(一):IOC容器
- Spring mvc + kindeditor items null
- 操作系统概论一
- vba 初试
- 有关语音识别方面资料的收集
- ORACLE的RAC的运行状态问题
- JDK源代码阅读笔记(一)------容器篇
- html学习记录
- 内核驱动之异常分析
- (转)关于无良培训机构的恶意抹黑疯狂Java的反驳(v2)
- windows phone:Windows Phone 7页面区域大小示意
- FPGA+CPLD中常见模块设计
- RSS feeds with Java
- \tutorial_code\core\mat_mask_operations
- 一次library cache pin故障的解决过程