先来看一张图:
从上我们可以看出,最顶端其实就是4个接口:Collection ,List ,Set ,和Map 。 其中List和Set是继承自Collection,而Map则自成一脉。这些接口都是在java.util路径下的,都属于java的基础类库rt.jar。
这里我们需要说明一下的是,java.util.Collections,是不属于java的集合框架的。它是一个集合的工具类。比如我们常用它的排序方法:Collections.sort(List), Collections.sort(List, Comparator)。
回到正题。上图中那么多的接口和类,各自的特性是什么呢?这是我们这篇文章关注的重点。我们可以知道,在这个图中,越是下面的子类,特性也就越丰富。而顶层的接口和类,也就越简单。我们在刚接触java的时候,用的最多的可能就是ArrayList和HashMap。我们常用的写法会是这样:
List<T> pList = new ArrayList<T>(); Map<K, V> pMap = new HashMap<K, V>();
List和Map最简单的区别就是:Map存放的是键值对,方便查找。
下面我们来看一张比较简单的表格,以区分各个类的差别:
| 是否有序 | 是否允许重复 | 是否线程同步 | |
Collection | 否 | 是 |
| |
List | ArrayList | 是 | 是 | 否 |
Vector | 是 | |||
LinkedList | 否 | |||
Set | HashSet | 否 | 否 | 否 |
TreeSet | 是 | 否 | ||
Map | HashMap | 否 | <key, value>, key不允许重复 | 否 |
TreeMap | 是 | 否 | ||
Hashtable | 否 | 是 |
可以知道,List是有序集合,而Set和Map则不一定。以Tree开头的都是有序的。而以Hash开头的,是用hash实现的,性能上比用二叉树实现的Tree**要好。
关于同步问题,一般而言,非同步的类,性能比同步的要好。我们建议用Collections.synchronizedCollection(Collection<T> c)方法去处理原本非同步的类,在不丢失性能的前提下,实现同步。Java1.5提供了ConcurrentHashMap,适用于高并发的线程安全实现。