ArrayList、Vector和LinkedList类均在java.util包中,都是可伸缩的数组,即可以动态改变数组的长度。
ArrayList和Vector都是基于存储元素的Object[]array来实现的,它们会在内存中开辟一块连续的空间来存储,由于数据存储是连续的,因此它们支持用序号(下标、索引)来访问元素,同时,索引数据的速度比较快。但是在插入元素的时候,需要移动容器中元素的位置,所以对数据的插入操作会比较慢。ArrayList和Vector都有一个初始化的容量大小,当里面存储的元素超过这个大小的时候,就需要动态扩容它们的空间。为了提高程序运行效率,每次扩容的时候,不是简单的扩充一个存储单元,而是一次增加多个存储单元。Vector默认扩充为原来的2倍(每次扩充的倍数是可以设置的),而Arraylist默认扩充到原来的1.5倍(没有提供方法来设置空间扩充的方法)。
ArrayList与Vector最大的区别就是synchronization(同步)的使用,没有一个ArrayList的方法是同步的,而Vector的绝大多数方法(例如add、insert、remove、set、equals和hashcode等)都是直接或间接同步的。所以,Vector是线程安全的,ArrayList是线程不安全的。正是由于Vector提供了线程安全的机制,使其性能上也要略逊于ArrayList。
LinkedList是采用双向列表来实现的,对数据的索引需要从头开始遍历。因此随机的访问效率比较低,但是插入元素的时候不需要对数据进行移动,故插入效率较高。同时,LinkedList不是线程安全的。
那么在实际使用时,如何从这几种容器中选择合适的容器呢?当对数据的主要操作为索引或者只在集合的末端增加、删除元素,使用ArrayList或Vector效率比较高。当对数据的操作主要为指定位置的插入或删除操作,使用LinkedList效率比较高。当在多线程中使用容器时(即多个线程会同时访问该容器),选用Vector较为安全。
HashMap和HashTable的区别如下:
Java为数据结构中的映射定义了一个接口java.util.map,它有3个实现类:HashMap、Hashtable和TreeMap。Map是用来存储键值对的数据结构,在数组中通过数组下标对其内容进行索引,而在Map中,则是通过对象来索引,用来索引的对象叫做key,其对应的对象叫做value。
HashMap是一个常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。由于HashMap与HashTable都采用了Hash方法进行索引,因此二者具有很多相似之处,这里主要列举二者的区别:
1)HashMap是HashTable的轻量级实现(非线程安全的实现),它们都实现了Map接口,主要区别于HashMap允许空(null)键值(key)(但需要注意,HashMap最多只能允许一条记录的键为null,不允许多条记录的值为null),而Hashtable不允许空(null)键值(key);
2)HashMap把Hashtable的contains方法去掉了,改成containvalue和containskey。因为contains方法容易引起误解。Hashtable继承自Dictionary类,而HashMap是Java 1.2引进的Map interface的一个实现;
3)Hashtable的方法是线程安全的,而HashMap由于不支持线程的同步,所以,它不是线程安全的。在多个线程访问Hashtable时,由于不需要开发人员对它进行同步,而对于HashMap,开发人员必须提供额外的同步机制。所以,效率上HashMap可能高于Hashtable;
4)Hashtable使用Enumeration进行遍历,HashMap使用Iterator进行遍历;
5)Hashtable和HashMap采用hash/rehash算法都几乎一样,所以,性能不会有很大的差异;
6)Hashtable中Hash数组的默认大小是11,增加的方式是old*2+1。在HashMap中,Hash数组的默认大小是16,而且一定是2的指数;
7)Hash值的使用不同,Hashtable直接使用的对象是Hashcode。
以上三种类型中,使用最多的是HashMap。HashMap里面存入的键-值对在取出的时候没有固定的顺序,是随机的。一般而言,在Map中插入、删除和定位元素,HashMap是最好的选择。由于TreeMap实现了SortMap的接口,能够把它保存的记录根据键排序,所以取出来的事排序后的键值对,如果需要按自然顺序或自定义顺序遍历键值对,那么TreeSet会更好。LinkedHashMap是HashMap 的一个子类,如果需要输出的顺序和输入的相同,可以用LinkedHashMap实现,它还可以按读取顺序来排列。