Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。Java平台的完整集合框架如下图所示:

上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。
发现一个特点,上述所有的集合Collection类,都实现了Iterator接口,(Map中并没有实现这个接口),这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口ListIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。
还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
将一些抽象类去掉之后的简化版如下图所示。

下面简单介绍下每一种集合类型的特点:
1 package edu.sjtu.erplab.collection;
2
3 import java.util.HashSet;
4 import java.util.Iterator;
5 import java.util.Set;
6
7 public class HashSetDemo {
8
9 public static void main(String[] args) {
10 Set<String> set=new HashSet<String>();
11
12 set.add("a");
13 set.add("b");
14 set.add("c");
15 set.add("c");
16 set.add("d");
17
18 //使用Iterator输出集合
19 Iterator<String> iter=set.iterator();
20 while(iter.hasNext())
21 {
22 System.out.print(iter.next()+" ");
23 }
24 System.out.println();
25 //使用For Each输出结合
26 for(String e:set)
27 {
28 System.out.print(e+" ");
29 }
30 System.out.println();
31
32 //使用toString输出集合
33 System.out.println(set);
34 }
35 }View Code 1 package edu.sjtu.erplab.collection;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6
7 public class ArrayListDemo {
8 public static void main(String[] args) {
9 List<String> arrList=new ArrayList<String>();
10
11 arrList.add("a");
12 arrList.add("b");
13 arrList.add("c");
14 arrList.add("c");
15 arrList.add("d");
16
17 //使用Iterator输出集合
18 Iterator<String> iter=arrList.iterator();
19 while(iter.hasNext())
20 {
21 System.out.print(iter.next()+" ");
22 }
23 System.out.println();
24 //使用For Each输出结合
25 for(String e:arrList)
26 {
27 System.out.print(e+" ");
28 }
29 System.out.println();
30
31 //使用toString输出集合
32 System.out.println(arrList);
33 }
34 } 1 package edu.sjtu.erplab.collection;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.ListIterator;
7
8 public class LinkedListTest {
9
10 public static void main(String[] args) {
11
12 List<String> a=new ArrayList<String>();
13 a.add("a");
14 a.add("b");
15 a.add("c");
16 System.out.println(a);
17
18 List<String> b=new ArrayList<String>();
19 b.add("d");
20 b.add("e");
21 b.add("f");
22 b.add("g");
23 System.out.println(b);
24
25 //ListIterator在Iterator基础上添加了add(),previous()和hasPrevious()方法
26 ListIterator<String> aIter=a.listIterator();
27 //普通的Iterator只有三个方法,hasNext(),next()和remove()
28 Iterator<String> bIter=b.iterator();
29
30 //b归并入a当中,间隔交叉得插入b中的元素
31 while(bIter.hasNext())
32 {
33 if(aIter.hasNext())
34 aIter.next();
35 aIter.add(bIter.next());
36 }
37 System.out.println(a);
38
39 //在b中每隔两个元素删除一个
40 bIter=b.iterator();
41
42 while(bIter.hasNext())
43 {
44 bIter.next();
45 if(bIter.hasNext())
46 {
47 bIter.next();//remove跟next是成对出现的,remove总是删除前序
48 bIter.remove();
49 }
50 }
51 System.out.println(b);
52
53 //删除a中所有的b中的元素
54 a.removeAll(b);
55 System.out.println(a);
56 }
57 }最后,看到了一些关于集合架构源码剖析的文章,有兴趣可以看一下,多了解内部原理也是挺好的。
各大类直接的区别可以参见:java中Map,List与Set的区别
探索equals()和hashCode()方法
http://blog.jobbole.com/101493/
java中的HashTable,HashMap和HashSet
注意:HashMap的初始化容量为16,负载因子为0.75,然后当其中的元素个数大于16*0.75时进行扩容,每次扩容会将容量扩大两倍。
HashSet的内部结构就是HashMap,只是每个键值对的值都确定为一个常量对象PRESENT(private static final Object PRESENT = new Object();)
http://blog.jobbole.com/101724/
注意:LinkedHashSet 和 LinkedHashMap之间的关系和HashSet与HashMap之间的关系是一样的。只是在其中加入了双向链表的结构。插入的时候依然按照HashMap的方式插入,只是在元素之间用双向链表表示前后的顺序,所以查找和插入都很快速。
http://blog.jobbole.com/102230/
java集合类TreeMap和TreeSet
注意:TreeSet 和 TreeMap之间的关系和HashSet与HashMap之间的关系是一样的。TreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator)。TreeMap底层通过红黑树(Red-Black tree)实现,也就意着containsKey(), get(), put(), remove()都有着log(n)的时间复杂度。
红黑树的原理:
http://blog.jobbole.com/103045/
《Thinking In Algorithm》07.Red-Black Trees(红黑树)
http://blog.jobbole.com/101796/
ArrayList与LinkedList的区别
注意:ArrayList的初始化容量为10,然后当其中的元素个数大于16*0.75时进行扩容,每次扩容会将容量扩大原先的1.5倍,eg:第一次扩容至10+10/2=15,第二次是15+15/2 = 22,以此类推。
http://blog.jobbole.com/101830/
注意:LinkedList中定义的双向链表的Node节点如下:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}