一、类图
二、基本抽象基类
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用来选择输出的顺序