一、ArrayList(数组)
1、如下代码执行,底层会初始化数组,即:Object[] elementData = {};
-
ArrayList<Stirng> list = new ArrayList<>();
2、首次添加元素时,会初始化数组elementData = new ObJect[10]; 之后再添加元素
-
list.add("AA");
3、当要添加第 11 个元素时,底层的 elementData数组已满,则需要扩容。默认扩容原来的 1.5 倍。并将原有数组中的元素复制到新的数组中
4、可以在创建是指定长度的数组
二、Vector(数组)
1、底层初始化数组,长度为10。 Object[] elementData = new Object[10];
-
Vector v = new Vector();
2、v.add(“AA”); //elementData[0] = “AA”;
3、当添加到第 11 个元素时,需要扩容,默认扩容为原来的 2 倍,但是,可以自定义扩容的长度的
三、LinkedList(双向链表)
1、底层就是简单的创建一个对象
-
LinkedList<String> list = new LinkedList<>();
2、将 “AA” 封装到一个 Node 对象1 中,list 对象的属性 first 、last 都指向此Node对象1
-
list.add("AA");
3、将 “BB” 封装到一个Node对象2 中,对象1和对象2构成一个双向链表,同时last指向此对象2
-
list.add("BB");
4、因为LinkedList使用的是双向链表,不需要考虑扩容问题
四、HashMap(jdk7)
1、创建对象的过程中,底层会初始化Entry[] table = new Entry[16];
-
HashMap<String,Integer> map = new HashMap<>();
2、将 “AA” 和 78 封装到一个Entry对象中,考虑将此对象添加到table数组中
-
mapo.put("AA",78);
3、具体的添加或修改过程(重点)
-
添加/修改的过程
-
将
(key1,value1)添加到当前的map中: -
首先需要调用
key1所在类的hashCode()的方法,计算key1对应的hash值1,将此hash值1经过hash()算法之后,得到hash值2,hash值2再经过indexFor()之后,就确定了(key1,value1)所在table数组中的位置索引i-
1.1 如果此索引位置
i的数组上没有元素,则(key1,value1)添加成功 ——> 情况1 -
1.2 如果此索引位置
i的数组上有元素(key2,value2),则需要继续比较key1和key2的hash值2——> 哈希冲突-
2.1 如果
key1的hash值2与key2的hash值2不相同,则(key1,value1)添加成功 — —> 情况2 -
2.2如果
key1的hash值2与key2的hash值2相同,则需要继续比较key1和key2的equals()。要调用key1所在类的equals()将key2作参数传递-
3.1 调用
equals(),返回 false :则(key1,value1)添加成功 — —> 情况3 -
3.1 调用
equals(),返回 true:则认为key1和key2相同。默认情况下,value1被替换为value2
-
-
-










