1 Collection接口
Collection
是最基本的集合接口,java SDK不允许其他类直接继承Collection
接口,只能继承Collection
的子接口List
或Set
接口。
以下是Collection
的部分子类层次图。
1.1 List接口
List
是有序的Collection
,用户可以准确在任何位置进行插入或删除,只需要根据索引就可以访问其中的元素。
List
的遍历方法除了Collection
所提供的Interator()
方法外,还有自己独有的listInterator()
方法,该方法除了可以对元素进行CRUD外,还可以向前向后遍历。
- ArrayList类
ArrayList
实现了可变长的数组,可以保存任何元素,包括null。
每个ArrayList
实例都有一个一个容量(Capacity),即集合用于存储元素的个数,容量会随着元素的增加自动增加。在需要插入大量元素时,在插入前可以调用ensureCapacity()方法来增加ArrayList
的容量以此来提高效率。
ArrayList
是线程不同步的。
- LinkedList类
LinkedList
实现了List
接口,允许添加null元素,LinkedList
还提供了独有的get、remove、insert方法进行操作,因此LinkedList
可以作为stack、queue、deque
来使用。
LinkedList
也是线程不同步的,如果多个线程同时访问LinkedList
,那么需要用户自己实现同步方法。其中一种解决方法是在创建list时构造一个同步list:
List list = Collection.synchronizedList(new LinkedList())
- Vector类
Vector
实现了List
接口,和ArrayList
类似,只是Vector
时线程同步的,当一个Vector
正在被使用的时候,其它线程对其操作,将会抛出ConcurrentModificationException
异常,因此用户需要对其捕获。
- Stack类
Stack
继承自Vector
类,实现了先进后出的堆栈。提供的五个方法使得可以作为栈来使用peek、empty、search、push、pop
,其中push、pop
方法可以向堆栈中添加和弹出元素,empty
方法判断当前堆栈是否为空,peek
方法查询当前栈顶元素并返回,search
方法查找元素在堆栈中的位置。
1.2 Set接口
Set
是一种不包含重复元素的Collection
,且最多只有一个null元素。
HashSet类
HashSet
类不允许出现重复元素,且是无序的,只能包含一个null元素。TreeSet类
TreeSet
类可以实现集合的排序,在对象向集合中添加时按照某种特定的规则去进行排序。
当用户没有自己定义排序时,将会按照自然排序。用户若需要自定义排序只需要实现Comparator
接口,并重写compare
方法。
2 Map接口
Map
没有继承Collection
,没有,没有,没有,重要的事需要说三遍。Map
是提供key到value的映射,且key不允许重复。以下是常用的Map
子类。
- HashTable类
HashTable
实现的Map
接口,实现了一个key-value的哈希表,任何非空的元素都可以当作key或value,且是同步的。
HashTable
通过init capacity
和load capacity
两个参数来调整性能。init capacity
是初始化时的集合容量大小,而load capacity
是当容量不够时自动添加的比例,缺省的大小为0.75,这样可以实现时间和空间的均衡,增大load capacity
时虽然会节省空间但相应的查找时间增加。
由于key对象是通过参列表来查找对应的value值,所以当key保存对象的时候,需要用户自己在该key对象中重写equals和hashCode
方法。
- HashMap类
HashMap
和HashTable
类似,不同之处在与HashMap
不是同步的,且可以将null元素作为key或value保存。
- WeakHashMap类
WeakHashMap
是一种改进的HashMap
,当key不在被外部所引用时,将会被GC回收。
3 汇总
如果涉及到堆栈,队列,那么应该使用List
,对于需要快速进行插入、修改、删除元素,应该优先使用LinkedList
,如果只是需要对元素进行查看访问,那么应该使用ArrayList
。
我们在创建一个对象时,应尽量的去返回该类型的接口,如创建ArrayList
返回List
,这样的好处就是当我们需要将ArrayList
转换成LinkedList
时将不需要改变客户端代码。
-
Vector和ArrayList
-
Vector
是线程安全的,而ArrayList
是线程不安全的, 如果不考虑线程的安全性,那么使用ArrayList
的效率会更高。
-
如果集合中的元素个数大于集合数组中的元素时,
Vector
每次会增加100%的长度,而ArrayList
只会增加50%的长度,当需要插入大量的元素时,使用Vector
更高效。如果要查找某个特定的元素时,
Vector
和ArrayList
花费的时间是相同的,若当要移动指定元素的位置时,使用LinkedList
则更加节省时间。-
ArrayList和LinkedList
ArrayList
是基于动态数组实现的数据结构,而LinkedList
是基于链表实现的数据结构。当只是需要随机访问get、set方法时,使用
ArrayList
更快,因为LinkedList
需要移动指针。当需要对集合数据斤进行增改时,
LinkedList
更为高效, 因为ArrayList
需要移动数据。
当然如果只是对一条数据进行增改时,ArrayList会更快,如果需要对大量数据进行增改时,显然LinkedList还是比ArrayList快。