一.     HashMap的一些其它讨论 
1.    关于HashMap中的key值的使用 
1.1.   以Java的库函数做为HashMap的key值时,可以直接使用。 
import java.util.*; 
class Counter{ 
    int i = 1; 
    public String toString(){ 
        return Integer.toString(i); 
    } 
} 
public class ExplicitStatic{    
    public static void main(String[] args){ 
        HashMap hm = new HashMap(); 
        for(int i = 0; i < 10000; i++) 
        { 
         //HashMap的key的类型为Integer 
            Integer r = new Integer((int) (Math.random() * 20)); 
            if(hm.containsKey(r)) 
                ((Counter)hm.get(r)).i++; 
            else 
                hm.put(r, new Counter()); 
        } 
        System.out.println(hm); 
    } 
} 
1.2.   如果在HashMap中使用你自己撰写的classes做为key,你一定得同时覆写hashCode()和equals()。 
下面代码用自己实现的class做为key,但没有覆写hashCode()和equals()。 
import java.util.*; 
class Groundhog{ 
    int ghNumber; 
    Groundhog(int n) { ghNumber = n; } 
    public String toString(){ 
        return "Groundhog@" + ghNumber; 
    } 
} 
class Prediction{ 
    boolean shadow = Math.random() > 0.5; 
     public String toString(){ 
        if(shadow) 
            return "Six more weeks of Winter!\n"; 
        else 
            return "Early Spring!\n"; 
    } 
}  
public class Test{    
    public static void main(String[] args){ 
        HashMap hm = new HashMap(); 
        for(int i = 1; i < 10; i++) 
            hm.put(new Groundhog(i), new Prediction()); 
        System.out.println("hm = " + hm); 
        System.out.println("Looking up prediction for Groundhog #3:"); 
        Groundhog gh = new Groundhog(3); 
        if(hm.containsKey(gh))  //(1) 
            System.out.println((Prediction)hm.get(gh));  
        else 
            System.out.println("Key not found: " + gh); 
    } 
} 
运行结果: 
hm = {Groundhog@9=Early Spring! 
, Groundhog@8=Six more weeks of Winter! 
, Groundhog@7=Six more weeks of Winter! 
, Groundhog@6=Early Spring! 
, Groundhog@5=Early Spring! 
, Groundhog@4=Early Spring! 
, Groundhog@3=Early Spring! 
, Groundhog@2=Early Spring! 
, Groundhog@1=Six more weeks of Winter! 
} 
Looking up prediction for Groundhog #3: 
Key not found: Groundhog@3 
key没覆写hashCode()和equals(),那么在通过key取得hash code时,就会取得key的内存地址;同样,当通过equals()函数比较两个key是否相等时,比较的也是两个key的地址。所以(1)处代码比较的结果为false(因为两个对象的内存地址肯定是不相同的)。显然,这不是我们要得到的结果。 
为了要得到正确的结果,我们只需在作为key的类中实现hashCode()和equals()。 : import java.util.*; 
class Groundhog2{ 
    int ghNumber; 
    Groundhog2(int n) { ghNumber = n; } 
    public String toString(){ 
        return "Groundhog2@" + ghNumber; 
    } 
/** 
     * 以ghNumber作为hash code 
     */ 
    public int hashCode() { return ghNumber; } 
/** 
     *比较的是两个key的ghNumber值 
     */ 
    public boolean equals(Object o) 
    { 
        return (o instanceof Groundhog2)  
            && (ghNumber == ((Groundhog2)o).ghNumber); 
    } 
} 
class Prediction{ 
    boolean shadow = Math.random() > 0.5; 
    public String toString(){ 
        if(shadow) 
            return "Six more weeks of Winter!\n"; 
        else 
            return "Early Spring!\n"; 
    } 
} 
public class Test{    
    public static void main(String[] args){ 
        HashMap hm = new HashMap(); 
         for(int i = 1; i < 10; i++) 
            hm.put(new Groundhog2(i), new Prediction()); 
        System.out.println("size = " + hm.size() + " , hm = " + hm); 
        System.out.println("Looking up prediction for Groundhog #3:"); 
        Groundhog2 gh = new Groundhog2(2); 
        if(hm.containsKey(gh)) 
            System.out.println((Prediction)hm.get(gh)); 
        else 
            System.out.println("Key not found: " + gh); 
    } 
} 
运行结果为: 
hm = {Groundhog2@9=Early Spring! 
, Groundhog2@8=Six more weeks of Winter! 
, Groundhog2@7=Six more weeks of Winter! 
, Groundhog2@6=Six more weeks of Winter! 
, Groundhog2@5=Early Spring! 
, Groundhog2@4=Early Spring! 
, Groundhog2@3=Six more weeks of Winter! 
, Groundhog2@2=Early Spring! 
, Groundhog2@1=Early Spring! 
} 
Looking up prediction for Groundhog #3: 
Early Spring! 
在新的代码中,我们在作为key的类中实现了hashCode()和equals()函数,得到了想要的结果。 
2.    HashMap的效能因子 
Capacity:容量,表格中的buckets数量 
Initial capacity:初始容量,表格建立之初的buckets数量。 
HashMap和HashSet:各有构造函数,允许指定初始容量。 
Size:大小,表格内目前所有的条目。 
Load factor:负载因子,size / capacity(大小/容量)。负载因子为0,表示一个空表格,0.5是一个半满表格,依此类推。一个轻负载表格出现碰撞(collisions)的机会比较低,比较适合安插和查找(但会降低“通过迭代器巡访”的速度)。在HashMap和HashSet各有构造函数中指定了负载因子后,当容器达到这个负载因子,容器的容量(buckets个数)就会自动扩充,并将原有的对象重新导入到新的buckets内(这称为rechashing)。HashMap缺省的负载因子值是0.75。  
 
  |