您的位置:首页 > 编程语言 > Java开发

Java集合框架

2015-12-30 23:32 549 查看

Java开发中经常使用到的类:



可以看出,Java的集合框架包含三大部分:List、Set和Map,其中List和Set在类继承和接口实现上有交集,而Map则是孤立的。

List

一、ArrayList

最常用到的集合类,内部使用数组实现,因此它具有O(1)时间复杂度按位置查找元素的优点,不过插入和删除元素需要O(n)。主要特点:

1.允许null(这是必然的,因为数组元素本来就可以指向null)。

2.在创建一个ArrayList,如果不指定初始大小,那么默认大小是10,但是要注意,不是在new的时候就马上进行扩容,而是在第一次添加元素时才会扩容为默认大小(不够的话继续扩大到刚好足够为止),这个可以查看源代码和利用反射进行验证。

3.扩容方法:如果容量足够,那么不管;如果容量不够,那么先扩大为原来的1.5倍,此时如果还是不够那么直接扩大到刚刚好容纳要添加的所有元素为止。

4.每次扩容都会调用Arrays.copyOf方法,因此比较耗时,在知道或者可以预测List的大小时应该指定其初始大小。

5..实现了Serializable接口。

二、LinkedList

内部使用双向循环链表(带表头节点)实现,添加删除元素快,但是查找效率比ArrayList低。主要特点:

1.允许null。

2.实现了Serializable接口。

三、Vector

相对线程安全List,效率不高,基本不适用,主要特点:

1.接受null。

2.相对线程安全,使用的锁是this,这是效率低的原因,比如有一个线程在调用get方法,另一个线程在调用size方法,它们都需要竞争this锁,但其实这种竞争是没有必要的,甚至在一个线程在迭代一个Vector的元素时其它线程调用该Vector对象的其它方法时会因为得不到锁而阻塞。

四、Stack

基本不用,主要特点:

1.继承自Vector,因此也拥有Vector的许多操作,看起来不像真正的栈。

Map

一、HashMap

基于散列方法实现Map接口,采用拉链法解决地址冲突,主要特点:

1.key和value都允许null。

2.非线程安全。

3.默认大小为16,HashMap要求大小一定要是2的n次幂,原因是可以更少地发生地址冲突,如果指定一个不是2的次幂的大小,那么会被调整为比该值大的最接近的2的次幂的值。

4.扩容因子默认为0.75。

5.使用key的hashcode重新计算哈希码。

二、Hashtable

由于Hashtable效率不高,一般如果需要线程安全都会使用Collections.synchronizedMap或者ConcurrentHashMap,主要特点:

1.key和value不允许为null,否则会抛出空指针异常。

2.相对线程安全,以this为锁。

3.默认大小为11。

4.扩容时尝试增大为原来的2倍+1。

5.直接使用key的hashcode。

6.使用拉链法解决地址冲突。

7.扩容界限因子默认为0.75。

三、LinkedHashMap

链式实现的HashMap,主要特点:

1.继承自HashMap,因此key和value允许null。

2.实际有两份数据,一份为HashMap中的,一份采用双向循环链表存储,注意链表有表头节点。

3.accessOrder成员布尔变量表示链表按什么顺序排序,默认为false表示按插入顺序排序(注意覆盖不影响顺序),

因此遍历LinkedHashMap得到的就是插入顺序,如果为true表示按访问排序,最近访问的会被放在链表尾部,可以利用这一特点实现LRU算法,但你必须重写removeEldestEntry确定什么时候移除最少使用到的节点。

四、WeakHashMap

主要特点:

1.类似HashMap。

2.key采用WeakReference保存。

五、TreeMap

1.基于红黑树实现,注意并不是二叉搜索树

2.key不允许null,value允许null。

3.作为key的类类型必须实现Comparable接口,否则会报类转型异常。

Set

一、HashSet

1.允许null。

2.内部使用HashMap实现,因此遍历顺序并不就是插入顺序。

3.所有值都是存储在HashMap的key中的,而所有的value都被设置为同一个虚拟对象。

二、LinkedHashSet

1.允许null。

2.继承自HashSet,内部使用LinkedHashMap(注意它是通过HashMap的一个包级别构造函数实现的),能保证遍历顺序与插入顺序相同。

三、TreeSet

1.内部使用TreeMap实现,因此不允许null。

其它

1.Comparable接口与Comparator区别:前者位于java.lang包下,只能比较相同类实例,后者位于java.util包下,可以比较不同类实例;同时Collections调用方法不同。

2.Collections类提供了一系列静态方法用于集合的相关操作。

3.clone调用的是Arrays的copyOf方法,也就是System的arraycopy方法,因此是浅拷贝。Collections的copy也是浅拷贝。如果要实现彻底深度拷贝可以采用对象序列化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: