JAVA集合知识点汇总
JAVA中容器分为Collection和Map
Collection是线性集合,而Map是典型的Key-value数组+链表(本质上是一个映射)形式。
1、有关List的set()方法、ArrayList扩容相关
1.public E set(int index, E element)其功能是覆盖掉原index位置上的元素,注意!!!index位置上必须有数据才可操作,否则报IndexOutOfBoundsException异常。
源码ArraList判断如下:
if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
2.ArrayList扩容(jdk1.7):
当创建一个List时,如List a = new ArrayList(20);会分配20个空间。
当第21个元素添加进来时,判断需要的空间是否大于当前数组长度,即21>20,源码:
if (minCapacity - elementData.length > 0) grow(minCapacity);
进行扩容且扩容1.5倍(右移1位,源码:int newCapacity = oldCapacity + (oldCapacity >> 1);),即将数组复制到更大的数组中。
2.ArrayList 和 LinkedList 的区别是什么?
-
ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
-
对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。LinkedList是链表形式,链表的优点就是增、删快。而ArrayList是是典型的数组,数组的优点是查快。
-
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。最大的时间差距在ArrayList需要扩容、复制、将左边的数据集体右移。在查找时,由于数组在分配空间时就是连续的,而LinkedList需要去不断寻址。
3.Array 和 ArrayList 有何区别?
-
Array 可以包含基本数据类型和引用类型,ArrayList只能包含引用类型。
-
ArrayList是基于数组实现的,Array大小不可以调整大小,但ArrayList可以通过内部方法自动调整容量。
-
ArrayList是List接口的实现类,相比Array支持更多的方法和特性。
4.Vector是线程安全的。
5.JDK1.8中的HashMap
- HashMap几乎可以等价于Hashtable(不过效率是有差距的,毕竟HashTable加了锁),
除了HashMap是非线程安全(没加synchronized)的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。并且去掉了HashTable的contains方法改成 containsValue 和 containsKey
- 有关HashMap放入新元素时有哪些操作。调用put方法是很简单的,但是put方法内部真的做了超级多事情。
首先HashMap存放的数据都是Node节点,Node节点有hash(int型),key,value,下一个Node引用。如下图所示:
在put时,会判断map的数据集table是否为空,空就创建一个数组用于存放Node。
如果当前位置为空,则创建一个新的Node放入table数组中。如图所示:
如果这个hash值的位置有数据了,并且key相等,则覆盖。
如果是TreeNode,就放入树中。
其他情况下,尾插。1.8之前是头插法,据说是为了避免死循环(多线程下resize导致),等查好了更新此处。
至于为什么hash冲突数大于8这个数作为链表转树的临界值,注释中说是按照帕松公式来的。。。链表中元素个数为8时的概率已经非常小。。。所以转成树的消耗是值得的。