在使用JAVA的时候经常用到集合类(有时也称容器类),下面对常用的容器类进行一下总结。首先看一张图,了解一下集合类的结构以及他们之间的关系:
一、Collection接口
Collection接口是 Set 、List 和 Queue 接口的父接口,提供了多数集合常用的方法声明,包括 add()、remove()、contains() 、size() 、iterator() 等。
其中各个方法的具体用法就不再一一介绍了。
二、几个比较重要的接口和类的介绍
1、List接口
List 关心的是索引,与其他集合相比,List特有的就是和索引相关的一些方法:get(int index) 、 add(int index,Object o) 、 indexOf(Object o) ;List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组;另外List允许有相同的元素。
ArrayList 可以将它理解成一个可增长的数组,它提供快速迭代和快速随机访问的能力,其底层使用数组实现的,查询效率较高,但是增删效率低且是线程不安全的。
LinkedList 中的元素之间是双链接的,当需要快速插入和删除时LinkedList成为List中的不二选择,其底层使用双向循环链表实现,查询效率低,但增删元素效率比较高。
Vector 是ArrayList的线程安全版本,性能比ArrayList要低,现在已经很少使用。
2、Set接口
Set关心唯一性,它不允许重复。
HashSet 当不希望集合中有重复值,并且不关心元素之间的顺序时可以使用此类,使用哈希算法实现。
LinkedHashset 当不希望集合中有重复值,并且希望按照元素的插入顺序进行迭代遍历时可采用此类。
TreeSet 当不希望集合中有重复值,并且希望按照元素的自然顺序进行排序时可以采用此类。(自然顺序意思是某种和插入顺序无关,而是和元素本身的内容和特质有关的排序方式,譬如“abc”排在“abd”前面。)
3、Queue接口
Queue用于保存将要执行的任务列表。
LinkedList 同样实现了Queue接口,可以实现先进先出的队列。
PriorityQueue 用来创建自然排序的优先级队列。
4、Map接口
Map关心的是唯一的标识符。他将唯一的键映射到某个元素。当然键和值都是对象。
HashMap 当需要键值对表示,又不关心顺序时可采用HashMap,线程不安全,允许key或value为NULL。
Hashtable 注意Hashtable中的t是小写的,它是HashMap的线程安全版本,不允许key或value为NULL。
LinkedHashMap 当需要键值对,并且关心插入顺序时可采用它。
TreeMap 当需要键值对,并关心元素的自然排序时可采用它。
三.Java常用集合比较及使用场景
1.List类和Set类
List类和Set类是Collection集合接口的子接口。
Set子接口:无序,不允许重复。
List子接口:有序,可以有重复元素。
Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
Set和List具体子类:
Set
|————HashSet:以哈希表的形式存放元素,插入删除速度很快。
List
|————ArrayList:动态数组
|————LinkedList:链表、队列、堆栈。
Array和java.util.Vector
Vector是一种老的动态数组,是线程同步的,效率很低,一般不赞成使用。
2.HashMap和HashTable
a.HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。
b.HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。
c.HashMap允许空键值,而HashTable不允许。
3.线程安全集合类与非线程安全集合类
LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;
HashMap是非线程安全的,HashTable是线程安全的;
StringBuilder是非线程安全的,StringBuffer是线程安全的。
4.集合适用场景
对于查找和删除较为频繁,且元素数量较多的应用,Set或Map是更好的选择
ArrayList适用于通过为位置来读取元素的场景
LinkedList 适用于要头尾操作或插入指定位置的场景
Vector 适用于要线程安全的ArrayList的场景
Stack 适用于线程安全的LIFO场景
HashSet 适用于对排序没有要求的非重复元素的存放
TreeSet 适用于要排序的非重复元素的存放
HashMap 适用于大部分key-value的存取场景
TreeMap 适用于需排序存放的key-value场景