1.Map概览
Java SE中有四种常见的Map实现——HashMap,TreeMap,Hashtable,LinkedHashMap。如果我们使用一句话来概括它们的特点,就是:
   HashMap就是一张
hash表,键和值都没有排序。
   TreeMap以红-黑树结构为基础,键值按顺序排序
   LinkedHashMap保存了插入时的顺序。
   Hashtable是
同步的(而HashMap是不同步的)。所以如果在
线程安全的环境下应该多使用      
   HashMap,而不是hashtable,因为Hashtable对线程的同步有额外的开销
   
2.HashMap
   如果HashMap的键(key)是
自定义的对象,那么需要按规则定义它的equals()和hashCode()方法
   
class="java" name="code">
    public class TestHashMap  {
    public static void main(String[] args){
         HashMap<Dog,Integer>  hashMap=new HashMap<Dog,Integer>();
         Dog d1=new Dog("red");
         Dog d2=new Dog("black");
         Dog d3=new Dog("white");
         Dog d4=new Dog("white");
         
         hashMap.put(d1,10);
         hashMap.put(d2,15);
         hashMap.put(d3,5);
         hashMap.put(d4,20);
         
         System.out.println(hashMap.size());
         for(Map.Entry<Dog,Integer> entry:hashMap.entrySet()){
             System.out.println(entry.getKey().toString() + " - " 
             +    entry.getValue());
         }
    }
}
   class Dog{
      String color;
     Dog(String c){
       color=c;
     }
  
     public String toString(){
         return color+" dog";
     }
   }
   
   输出:
   
    4
     white dog - 5
     black dog - 15
     red dog - 10
     white dog - 20
   
注意,我们
错误的将"white dogs"添加了两次,但是HashMap却接受了两只" white dogs"。这不
合理(因为HashMap的键不应该重复),我们会搞不清楚真正有多少白色的存在。Dog类应该定义如下:
   
    class Dog{
       String color;
       Dog(String c){
         color=c;
       }
       public boolean equals(Object o) {
          return ((Dog) o).color == this.color;
       }
       public int hashCode(){
         return color.length();
       }
       public String toString(){
         return color+" dog";
       }
    }
   
   现在输出结果如下:
   
    3
    red dog - 10
    white dog - 20
    black dog - 15
   
输出结果如上是因为HashMap不允许有两个相等的元素存在。默认情况下(也就是类没有实现hashCode()和equals()方法时),会使用Object类中的这两个方法。Object类中的hashCode()对于不同的对象会返回不同的整数,而只有两个引用指向的同样的对象时equals()才会返回true。
3. TreeMap
TreeMap的键按顺序排序。让我们先看个
例子看看什么叫作"键按顺序排列"
  
   class Dog {
	String color;
 
	Dog(String c) {
		color = c;
	}
	public boolean equals(Object o) {
		return ((Dog) o).color == this.color;
	}
 
	public int hashCode() {
		return color.length();
	}
	public String toString(){	
		return color + " dog";
	}
     }
 
     public class TestTreeMap {
	public static void main(String[] args) {
		Dog d1 = new Dog("red");
		Dog d2 = new Dog("black");
		Dog d3 = new Dog("white");
		Dog d4 = new Dog("white");
 
		TreeMap<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
		treeMap.put(d1, 10);
		treeMap.put(d2, 15);
		treeMap.put(d3, 5);
		treeMap.put(d4, 20);
 
		for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
			System.out.println(entry.getKey() + " - " +
                        entry.getValue());
		}
	}
   }
  
  输出:
  
   Exception in thread "main" java.lang.ClassCastException: collection.Dog cannot 
   be cast to java.lang.Comparable
	at java.util.TreeMap.put(Unknown Source)
	at collection.TestHashMap.main(TestHashMap.java:35)
  
  因为TreeMap按照键的顺序进行排列对象,所以键的对象之间需要能够比较,所以就要实现
  Comparable
接口。你可以使用String作为键,String已经实现了Comparable接口。
  
   class Dog implements Comparable<Dog>{
	String color;
	int size;
 
	Dog(String c, int s) {
		color = c;
		size = s;
	}
 
	public String toString(){	
		return color + " dog";
	}
 
	@Override
	public int compareTo(Dog o) {
		return  o.size - this.size;
	}
    }
 
    public class TestTreeMap {
	public static void main(String[] args) {
		Dog d1 = new Dog("red", 30);
		Dog d2 = new Dog("black", 20);
		Dog d3 = new Dog("white", 10);
		Dog d4 = new Dog("white", 10);
 
		TreeMap<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
		treeMap.put(d1, 10);
		treeMap.put(d2, 15);
		treeMap.put(d3, 5);
		treeMap.put(d4, 20);
 
		for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
			System.out.println(entry.getKey() + " - " + 
                        entry.getValue());
		}
	}
    }
  
  输出
  
  red dog - 10
  black dog - 15
  white dog - 20
  
  结果根据键的排列顺序进行输出,在我们的例子中根据size排序的。
  如果我们将“Dog d4 = new Dog(“white”, 10);”替换成“Dog d4 = new 
  Dog(“white”, 40);”,那么输出会变成:
  
  white dog - 20
  red dog - 10
  black dog - 15
  white dog - 5
  
  这是因为TreeMap使用compareTo()方法来比较键值的大小,size不相等的狗是不同的狗。
4. Hashtable
  Java文档写到:
  HashMap类和Hashtable类几乎相同,不同之处在于HashMap是不同步的,也不允许接受null键和null值。
5. LinkedHashMap
LinkedHashMap is a subclass of HashMap. That means it inherits the features of HashMap. In addition, the linked list preserves the insertion-order.
Let’s replace the HashMap with LinkedHashMap using the same code used for HashMap.
LinkedHashMap是HashMap的子类,所以LinkedHashMap继承了HashMap的一些属性,他在HashMap基础上增加的特性就是保存了插入对象的顺序。
  
  class Dog {
	String color;
 
	Dog(String c) {
		color = c;
	}
 
	public boolean equals(Object o) {
		return ((Dog) o).color == this.color;
	}
 
	public int hashCode() {
		return color.length();
	}
 
	public String toString(){	
		return color + " dog";
	}
   }
 
   public class TestHashMap {
	public static void main(String[] args) {
 
		Dog d1 = new Dog("red");
		Dog d2 = new Dog("black");
		Dog d3 = new Dog("white");
		Dog d4 = new Dog("white");
 
		LinkedHashMap<Dog, Integer> linkedHashMap = 
                new LinkedHashMap<Dog, Integer>();
		linkedHashMap.put(d1, 10);
		linkedHashMap.put(d2, 15);
		linkedHashMap.put(d3, 5);
		linkedHashMap.put(d4, 20);
 
		for (Entry<Dog, Integer> entry : linkedHashMap.entrySet()) {
			System.out.println(entry.getKey() + " - " +
                        entry.getValue());
		}		
	}
   }
  
  输出
  
   red dog - 10
   white dog - 20
   black dog - 15