在java中,集合主要是为了保存数量不确定的数据,以及保存具有映射关系的数据。集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象;而集合里只能保存对象。
java的集合类主要由两个接口派生出来:Collection和Map,Collection和Map是java集合框架的根接口,这两个接口又包含了一些子接口或实现类。如下图所示,是Collection和Map体系的继承树:
图一 Collection和Map体系的继承树
List特点:元素有放入顺序,元素可重复
Map特点:元素按键值对存储,无放入顺序
Set特点:元素无放入顺序,元素不可重复
一、List接口
List接口有三个实现类:LinkedList,ArrayList,Vector
1.LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址,链表增删快,查找慢
2.ArrayList:ArrayList是非线程安全的,效率高,可以放入null值,所以在便利ArrayList时一般要注意判断是否是null。
3.Vector:是基于线程安全的,所以效率相对较低
二、Set接口
1.HashSet类
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化;
HashSet不是同步的,如果多个线程同事访问一个HashSet,假设有两个或者两个以上的线程同时修改了HashSet集合时,则必须通过代码来保证其同步;
集合元素可以是null.
2.TreeSet类
TreeSet是SortedSet接口的实现类,正如SortedSet名字所暗示的,TreeSet可以确保集合元素处于排序状态
3.EnumSet类
EnumSet是专为枚举类设计的集合类,EnumSet中的所有元素都必须是指定的枚举类型的枚举值。EnumSet的集合元素也是有序的,EnumSet以枚举值在Enum类内的定义顺序来决定集合元素的顺序。
三、Map接口
Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value都是任何引用类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false。
1.HashMap类和Hashtable类
HashMap和Hashtable都是Map接口的典型实现类,它们之间的关系完全类似于ArrayList和Vector的关系,两者的区别如下:
Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现,所以HashMap比Hashtable的性能高一点;但如果多个线程访问同一个Map对象时,使用Hashtable实现类会更好。
Hashtable不允许使用null作为key和value,如果师徒把null值放进Hashtable中,将会引发NullPointerException异常;但HashMap可以使用null作为key和value。由于HashMap里的key不能重复,所以HashMap里最多最多只有一个key-value对的key为null,但可以有无数个key-value对的value为null。
2.TreeMap类
使用TreeMap有一个好处:TreeMap中的key-value对总是处于有序状态,无须专门进行排序操作。当TreeMap被填充之后,就可以调用keySet(),取得由key组成的Set,然后使用toArray方法生成key的数组,接下来使用Arrays的binarySearch()方法在已排序的数组中快速地寻找对象。
TreeMap通常比HashMap、HashTable要慢,尤其在插入、删除key-value对时更慢。
3.EnumMap类
EnumMap是一个与枚举类一起使用的Map实现,EnumMap中所有的key都必须是单个枚举类的枚举值。它具有如下特征:
EnumMap在内部以数组形式保存,所以这种实现形式非常紧凑、高效。
EnumMap根据key的自然顺序(即枚举值在枚举类中的定义顺序)来维护key-value对的顺序。当程序通过keySet()、entrySet()、values()等方法遍历EnumMap时可以看到这种顺序。
EnumMap不允许使用null作为key,但允许使用null作为value。