引言
在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类)。所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework)。常用集合类继承关系如下图:
![]()
下面对每个类进行详细解释。
Collection接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。下图为Collection接口的常用方法:
![]()
List接口
List是 有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户 能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组,List 允许有相同的元素。List除了具有Collection的所有方法外,还具有以下自己的方法:
![]()
很明显可以看出来,这些新增的方法都是与索引有关的。
ArrayList类
1.ArrayList 使用一个内置的数组来存储元素,允许null元素,这个数组的起始容量是10.当数组需要增长时,新的容量按如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费是由 ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分配以便能够增加新的元素。2.ArrayList是 非同步的,如果多个线程同时操作同一个ArrayList就会出现线程安全问题,这时候我们可以考虑使用java.util.concurrent包中定义的CopyOnWriteArrayList,它是线程安全的Arraylist。3.因为数组的特性,所以ArrayList对于随机访问的性能较高,而对于在集合中间增删元素性能较差。4.它有如下两个新增方法:
(1) void ensureCapacity(int minCapacity): 将ArrayList对象容量增加minCapacity
(2) void trimToSize(): 整理ArrayList对象容量为列表当前大小。程序可使用这个操作减少ArrayList对象存储空间。
LinkedList类
1.LinkedList内部使用链表实现,允许null元素。
2.LinkedList还提供额外的getLast / getFirst,removeLast / removeFirst,insertLast / insertFirst 方法操作 LinkedList的首部或尾部的元素。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
3.LinkedList也是 非同步的,如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:List list=Collections.synchronizedList(newLinkedList(...))。
4.因为链表的特性,所以LinkedList在集合中间增删元素比ArrayList性能较好。
Set接口
Set具有与Collection完全一样的接口,因此没有任何额外的功能,Set与Collection只是行为不同。(这是继承与多态思想的典型应用:表现不同的行为)存入Set的每个元素都必须是唯一的,因为Set 不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。
HashSet类
1.HashSet的底层使用Hash表的形式存储对象,它不保证元素的存储顺序,顺序有可能发生变化。
2.HashSet是 非同步的,使用Collections.synchronizedSet()可以实现同步。
3.HashSet允许放null元素,且只能有一个。
4.HashSet 为查找速度进行了优化,因此它的查找效率相对较高。
5.当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。如果该位置没有元素,则直接放入该位置,如果该位置有元素,调用equals()方法判断两个元素是否相同,如果相同,则舍弃,如果不同,则放到其他位置。所以要添加的对象须重写hashCode()和equals()方法。
LinkedHashSet类
具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
TreeSet类
1.TreeSet的底层使用红黑树结构,每个节点都会保存三个指针对象,分别指向父节点,左分支,右分支。2.TreeSet是保持次序的Set,它在添加元素时会调用compareTo()方法来 确定保存的次序(即可以按指定的属性进行排序),所以要添加的对象须实现Comparable或Comparator接口,并重写ComparaTo()方法。3.TreeSet也是非同步的,使用Collections.synchronizedSet()可以实现同步。
Map接口
java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap。Map主要用于存储健值对,根据键得到值,因此不允许键重复,但允许值重复。Map的常用方法如下:
![]()
HashMap类
类似于HashSet,这两个类的实现思想基本相同,只不过HashMap是以键值对的形式存储元素,它的Key就相当于一个HashSet。
TreeMap类
类似于TreeSet,这两个类的实现思想基本相同,只不过TreeMap是以键值对的形式存贮元素,它的Key就相当于一个TreeSet。
HashTable类
HashTable类似于HashMap,他们的区别是:1.HashTable是同步的,HashMap是非同步的,但是我们可以通过Collection.synchronizedMap(hashmap) 使其实现同步。2.HashMap的Key和Value都允许为null,而HashTable的key和value都不允许为null。HashMap遇到key为null的时候,调用putForNullkey方法进行处理,而对Value没有处理,HashTable遇到为null的时候,直接返回NullPointerException。
LinkedHashMap类
LinkedHashMap和HashMap的关系类似于LinkedHashSet和HashSet的关系,这里就不多说。