一、常用的数据结构collection接口和map接口:
1、collection接口(List【ArrayList、LinkedList】、Set【HashSet(LinkedHashMap)、TreeSet】)
--List
----ArrayList
----LinkedList
----Vector
--Set
----HashSet
----LinkedHashMap
----TreeSet
2、map接口(HashMap【LinkedHashMap】、TreeMap)
--HashMap
----LinkedHashMap
--HashTable
--TreeMap
二、常见的一些区别
1、List、Set、Map的区别:
List是有序、元素可以重复的集合
Set是无序、元素不可以重复的集合
Map中的数据是键值对,键对象唯一,值可以重复
2、ArrayList、LinkedList、Vector的差异以及存储特性:
ArrayList是实现了基于动态数组的数据结构
LinkedList基于链表的数据结构
Vector也是一个类似于ArrayList的可变长度的数组类型
ArrayList与Vector的差异:
1)同步性:ArrayList不是线程安全的,Vector是线程安全的
2)扩容:当需要扩容时,Vector默认增长一倍,而ArrayList却是一半
存储特性:
1)插入操作:LinkedList >> ArrayList >>Vector
LinkedList使用的是双向链表存储,插入时只需要记录本项数据的前后项即可,所以速度较快
ArrayList和Vector使用的是数组存储数据,此数组元素数大于实际存储的数据,插入时,涉及到数组元素的移动等内存操作,所以速度较慢
因为Vector是线程安全的,使用了synchronization方法,导致插入时,性能比ArrayList差
2)查询操作:ArrayList和Vector >>LinkedList
ArrayList和Vector使用的数组存储,查询时,只需要按序号索引元素即可,而LinkedList按序号索引数据需要进行遍历,所以LinkedList速度较慢
3、HashMap的设计:
1)HashMap是基于哈希表的Map接口的非同步实现,它实质上是一个链表数组,HashMap的底层就是一个数组结构,数组的每一项又是一个链表。
2)HashMap的存储:
使用put,先根据key的hashCode计算hash值,根据这个hash值得到元素在数组中的位置(即下标),如果数组的该位置上已经存放其他元素了,那就以链表的形式存放这个元素,新加的元素放在链头。
3)HashMap的读取:
使用get,首先根据计算key的HashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。
4)HashMap的resize(rehash):
当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度是固定的,所以为了提高查询效率,就要对HashMap数组进行扩容。
当HashMap中的元素个数草果数组的大小*loadFactor时,就会对数组进行扩容,loadFactor默认值为0.75。
例如:当数组大小为16时,如果HashMap中元素个数超过16*0.75=12(threshold,临界值)的时候,就把数组的大小扩展到2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap的元素个数时,那么预设元素的个数就能有效提高HashMap的性能。
4、HashMap和HashTable的区别:
1)HashMap没有排序,允许一个null键和多个null值,而HashTable不允许
2)HashMap把Hashtable的contains方法去掉了,改成了containsvalue和containsKey
3)HashTable继承自Dictionary类,HashMap是Java1.2引进的Map接口的实现
4)HashTable的方法是线程安全的,而HashMap不是