Collection和Map的学习笔记(jdk1.4.2)

来源:互联网 发布:linux cp dd 编辑:程序博客网 时间:2024/06/18 05:21

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();
    }
}

 
原创粉丝点击