- 实际上尽管只有四种容器:Map List Set 和Queue;但是每种接口都有不止一种实现发式,在实际应用种该如何选择呢?
- 一般情况下,选择不标准是各种接口及实现的性能,而性能主要由接口是由其底层数据结构来实现的。
- 特别说明:像Hashtable,Vector和Stack特征是过去遗留下来的类,目的只是为了支持老的程序,最好不要在新的程序种使用它们。
ArrayList和LinkedList都实现了List接口,所以无论选择哪一个基本的List操作都一样,但是ArrayList底层的数据实现是数组,而LinkedList底层的数据实现是双向链表,其中每个对象包含数据的同时还包含指向链表的前一个和后一个元素的指引;因此当需要经常插入 删除等操作时LinkedList就比较合适,否则就应该使用速度更快的ArrayList。
Set可以被实现为TreeSet HashSet 或LinkedHahSet
1.HashSet最常用,查询速度最快
2.LinkedHashSet保持元素插入的顺序
3.TreeSet基于TreeMap,生成一个总是处于排序状态的Set集
一般基于代码需要的操作频率和执行速度来选择。
在List接口中应该避免使用Vector,他只是用来向前兼容,才被适配到了List,最佳的做法是首选ArrayList,只有在需要大量增删中间元素的时候选择LinkedList,如果是数量固定的元素,可以直接使用数组实现。
对Set的选择:
1。HashSet的性能基本上总是比TreeSet好,特别是在添加和查询元素时,而这两个操作也是最重要的操作。TreeSet存在的唯一原因就是它可以维持元素的排序状态;所以当需要一个排好序的Set时,才应该选择TreeSet。因为内部结构支持排序,并且因为迭代是我们更有可能的操作,所以TreeSet迭代通常比HashSet块。而对于插入操作,LinkedHashSet比HashSet迭代代价要高很多,这是由于维护链表所带来的额外代价。
Map的选择:除了IdentityHashMap,所有的Map实现都会随着Map尺寸的变大而明显缓慢,但是查找的代价通常比插入小得多,这是一个好消息,因为我们执行查找的频率要远高于插入。
1.Hashtable的性能大体与HashMap相当,它们具有相同的底层存储机制和查询机制,现在一般用HashMap来代替Hashtable。
2.TreeMap要比HashMap要慢,与使用TreeSet一样,TreeMap是一种创建有序列表的方式,树的行为:总是保证有序且不需要进行特殊的排序。
3.LinkedHashMap在插入操作时比HashMap慢一些,因为需要维护散列数据结构的同时换药维护链表(以保持插入顺序),也正因为如此,它的迭代速度反而很快。
当使用Map时,第一选择应该是HashMap,只有当需要Map始终保持有序时,才使用TreeMap。
HashMap的性能因子。
可以同过手动调整HashMap来提高性能。
1.容量
2.初始容量
3.尺寸
4.负载因子 尺寸/容量 通过调整负载因子(在时间和空间代价上取得平衡)
HashMap默认的负载因子时0.75
HashSet和HashMap都具有允许指定负载因子的构造器,当负载到达负载因子水平式,容器将自动增加容量(桶位数),实现方式是容量大致加倍,并重新将现有对象分布到新的桶位集中(再散列),负载因子越大,越增加查找的代价。