Tag - collection

J.A.R.V.I.S

Life is not just Live

2019

Java古老的集合类之Vector

今天继续来看一下Java中古老的集合类-Vector

变量

1
2
3
4
5
6
//容器存储实体的底层数据结构,Vector也是使用数组来进行存储的
protected Object[] elementData;
//实体的数量
protected int elementCount;
//每次扩容时增加的长度,当为0是扩容原数组长度的两倍
protected int capacityIncrement;

从上面的变量可以得知,Vector也是使用数组来进行底层的数据存储,并且还设置了扩容容量。

12月 23 · 4 min

Java古老的集合类之Hashtable

Hashtable虽然现在不经常被用到,但是它作为Java最早的集合类,今天来看一下它的源码。

首先说明一个问题,在Java中大部分都是驼峰式写法,但是Hasbtable并没有采用这种写法。

继承与实现关系

1
2
3
public class Hashtable<K,V> 
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {}

可以看出它继承的是DictionaryHashMap并不是同一个父类。但是它也实现了MapCloneableSerializable接口。说明它可以被克隆,可以执行序列化。

变量

1
2
3
4
5
6
7
8
9
private transient Entry<?,?>[] table;

private transient int count;

private int threshold;

private float loadFactor;

private transient int modCount = 0;

来一个一个的解释每一个变量的意义:

  • table

与HashMap一样,利用数组作为底层的存储容器,并且添加了关键字transient。这个关键字的意思是在进行序列化的时候不会被序列化。这个关键字具体可以看一下这篇文章

  • count

表示容器中存储的数量

  • threshold

扩容阈值,当容器中的数量到达这个值后会进行扩容机制。这个值默认情况下为 (capacity* loadFactor)

  • loadFactor

扩容系数,默认为0.75f。

  • modCount

修改次数,当增加或删除时,这个值会进行加一。表示这个容器结构修改的次数。这个变量在迭代,序列化等操作、多线程的操作下都尽量保证了安全性。

12月 20 · 11 min

TreeMap源码学习

之前看过了HashMap,LinkedHashMap的源码,这次来看一下TreeMap的源码。

从这个名字就能看出,TreeMap底层使用的是树来进行存储的。

变量

1
2
3
4
5
6
7
8
9
//比较器,用于左右子树的判断。
//正常情况下,左子树为 1,父节点为 2,右子树为 3。如果比较器设置 3<1<2。则左子树为3,父节点为 1,右子树为 2。
private final Comparator<? super K> comparator;
//根节点
private transient Entry<K,V> root;
//容量
private transient int size = 0;
//修改的次数,在迭代和序列化时用到
private transient int modCount = 0;

看一下 root 节点的数据结构:

1
2
3
4
5
6
7
8
9
10
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;

...
}

由于有一个color=BLACK属性,所以底层数据结构应该是红黑树

11月 12 · 4 min

JAVA容器

8月 31 · 1 min

HashSet源码

8月 26 · 1 min

LinkedHashMap源码

LinkedHashMap结构图

LinkedHashMap继承了HashMap类,实现了Map接口。

他与HashMap的主要区别就是使用链表存储了每个节点的顺序。这样就能保证有序。

来看一下他的节点情况:

1
2
3
4
5
6
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}

从这里可以看出他使用了两个变量,beforeafter存储这个节点的前后顺序。

8月 22 · 6 min

HashMap源码学习

HashMap结构

画了一张结构图,欢迎指正。

变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* The default initial capacity - MUST be a power of two.
* 默认的容量,容量必须是2的幂
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 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.
* 最大的容量值 2的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 bin count threshold for using a tree rather than list for a
* bin. Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
* 链表的长度到达8之后转换为红黑树
*/
static final int TREEIFY_THRESHOLD = 8;

/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;

/**
* The smallest table capacity for which bins may be treeified.
* (Otherwise the table is resized if too many nodes in a bin.)
* Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
* between resizing and treeification thresholds.
*
*/
static final int MIN_TREEIFY_CAPACITY = 64;

// 存储的容器
transient Node<K,V>[] table;

/**
* Holds cached entrySet(). Note that AbstractMap fields are used
* for keySet() and values().
*/
transient Set<Map.Entry<K,V>> entrySet;

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

/**
* The number of times this HashMap has been structurally modified
* Structural modifications are those that change the number of mappings in
* the HashMap or otherwise modify its internal structure (e.g.,
* rehash). This field is used to make iterators on Collection-views of
* the HashMap fail-fast. (See ConcurrentModificationException).
* 结构修改的次数,每次增加和删除都修改这个数值
*/
transient int modCount;

/**
* The next size value at which to resize (capacity * load factor).
*
* @serial
*/
// (The javadoc description is true upon serialization.
// Additionally, if the table array has not been allocated, this
// field holds the initial array capacity, or zero signifying
// DEFAULT_INITIAL_CAPACITY.)
// 扩容的阈值,当键值对的数量超过这个值就会扩容
int threshold;

/**
* The load factor for the hash table.
* 负载系数
*/
final float loadFactor;

8月 22 · 17 min

LinkedList源码学习

8月 21 · 11 min

ArrayList源码学习

变量

1
2
3
4
5
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;
private int size;
  • DEFAULT_CAPACITY:默认的容量,当我们不指定容量时默认容量是10
  • EMPTY_ELEMENTDATA:空的数据集
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA:同上面的一样,都是空的数据集
  • elementData:保存的元素
  • size:元素长度,实际存储的元素数量

构造方法:

  • 无参的构造方法
1
2
3
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

很简单的一句话,将保存元素的变量进行初始化。

8月 20 · 9 min

0 %