1. Collection / Map的类、接口层次关系:
接口层次关系
Collection
├List
└Set
└SortedSet
Map
└SortedMap
类层次关系
Object
└AbstractCollection
├AbstractList
│├ArrayList
│├Vector
│└AbstractSequentialList
│ └LinkedList
└AbstractSet
├TreeSet
└HashSet
└LinkedHashSet
Object
└AbstractMap
├HashMap
│└LinkedHashMap
├IdentityHashMap
├TreeMap
└WeakedHashMap
Object
└Dictionary
└Hashtable
2. 集合特征
Collection:元素是否允许重复,元素是否有序。箱子(Bags或multisets多重集,即元素无序且允许重复)必须直接实现Collection接口。
List:元素允许重复,元素之间有序,且允许多个null元素。
Set:元素不允许重复,且顶多包含一个null元素(SortedSet为有序集)。
(元素重复:若e1.equals(e2),则e1和e2只能作为一个元素出现。)
Map:存储key-value的键值对,键不允许重复,允许一个null键。
HashSet / LinkedHashSet,ArrayList / LinkedList,HashMap / LinkedHashMap / IdentityHashMap / TreeMap的实现方法不支持同步(synchronized),多线程并发时可能出问题。多线程并发应该用:
Set s = Collections.synchronizedSet(new HashSet(...));
通过iterator()遍历元素时,若集合被其它线程修改,则抛ConcurrentModificationException异常。
3. 操作复杂度
对于add/remove/contains等基本操作,
TreeSet:O(log(n))
HashSet / LinkedHashSet: O(1)
......
附录:测试小程序:
package cn.itcast.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.WeakHashMap;
import sun.rmi.server.WeakClassHashMap;
public class CollectionTest {
public static void main(String[] args) {
//testList();
//testSet();
//testSyncronizedSet();
testMap();
}
// 重复插入相同元素,会覆盖原来元素
private static void testSet() {
// Set set = new HashSet(); // 用Hashtable存储元素
Set set = new LinkedHashSet(); // 使用双向链表保留元素插入的顺序
// Set set = new TreeSet(); // 用TreeMap存储元素(元素升序排列)
set.add(new Integer(5));
set.add(new Integer(6));
set.add(new Integer(1));
set.add(new Integer(1));
set.add(new Integer(-1));
set.add("set");
set.add("set");
//set.add(null); // TreeSet不允许插入null元素,否则抛NullPointer异常
//set.add(null);
System.out.println(set);
}
private static void testList() {
//List list = new ArrayList();
//List list = new Vector();
List list = new LinkedList();
list.add(new Integer(2));
list.add(new Integer(3));
list.add(new Integer(1));
//list.add(null);
//list.add(null);
for (Iterator iter = list.iterator(); iter.hasNext();) {
Integer e = (Integer) iter.next();
System.out.println(e);
}
System.out.println(list);
// 列表元素排序
Collections.sort(list);
System.out.println(list);
}
// 重复插入相同元素,会覆盖原来元素
private static void testMap() {
// Map map = new HashMap(); //
// Map map = new LinkedHashMap(); // 使用双向链表保留元素插入的顺序
// Map map = new TreeMap(); // 用TreeMap存储元素(元素升序排列)
// Map map = new WeakHashMap();
Map map = new IdentityHashMap();
map.put("1", "a");
map.put("1", "a1");
map.put("2", "b");
map.put("2", "b2");
map.put(null, null);
map.put(null, null);
System.out.println(map);
}
private static void testSyncronizedSet() {
//final Set set = new HashSet();
final Set set = Collections.synchronizedSet(new HashSet());
set.add("a");
set.add("b");
// 进程1遍历集合,进程2删除元素,插入sleep()进行线程切换
Runnable r1 = new Runnable() {
public void run() {
System.out.println("r1 starting...");
for (Iterator iter = set.iterator(); iter.hasNext();) {
Object o = (Object) iter.next();
// 主动睡眠,切换线程
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("r1 finished.");
}
};
Runnable r2 = new Runnable() {
public void run() {
System.out.println("r2 starting...");
//set.remove("a");
Iterator iter = set.iterator();
iter.next();
iter.remove();
// 主动睡眠,切换线程
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("r2 finished.");
}
};
new Thread(r1).start();
new Thread(r2).start();
}
}