1. 程式人生 > >hashtable對字串的碰撞以及原始碼解析(非常適合新手理解hashtable)

hashtable對字串的碰撞以及原始碼解析(非常適合新手理解hashtable)

首先我從網上摘抄了三個典型的例子,非常適合來介紹hashtable對字串的碰撞。

第一個例子,去除字串陣列中中多餘的字串。ps(建議現在還在用eclipse IDE的可以試試IntelliJ IDEA)
程式碼如下:

import java.util.Enumeration;
import java.util.Hashtable;

public class Main {
    public static void main(String[] args) {
        String[] mobile={"13811071500","13811071500","13811071501","13811071503"
,"13811071501"}; mobile=checkArray(mobile); for(int i=0;i<mobile.length;i++) System.out.println(mobile[i]); } public static String[] checkArray(String[] str){ Hashtable<String,String> hash = new Hashtable<String, String>(); for(int i = 0
;i < str.length;i++){ if(!hash.containsKey(str[i])){ hash.put(str[i],str[i]); } } Enumeration enumeration = hash.keys(); String[] str_new = new String[hash.size()]; int i = 0; while(enumeration.hasMoreElements()){ str_new[i] = enumeration.nextElement().toString(); i++; } return
str_new; } }

輸出結果為:
輸出結果
下面是對原始碼的解析:很多人可以在這裡有個困惑,為什麼不用Iterator而選擇用了Enumeration,我們從hash.keys()的原始碼看起

public synchronized Enumeration<K> keys() {
        return this.<K>getEnumeration(KEYS);
    }

可以看到原始碼返回的型別就是Enmeration型別,所以用Enumeration也不足為奇了。
看程式碼原始碼是一個非常好的習慣和學習方法。
下面我們看看hashtable中containsKey的原始碼:

 public synchronized boolean containsKey(Object key) {
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return true;
            }
        }
        return false;
    }

可以看到這個方法前用了synchronized來修飾,所以你一定會想到hashtable是執行緒同步安全的。
然後下面的一些程式碼也很好理解,計算hash值然後進行比對。
第二個例子:

import java.util.Enumeration;
import java.util.Hashtable;

public class Demo2 {
    public static void main(String[] args){
        String[] mobile1={"13811071500","13811071501","13811071502","13811071503","13811071504"};
        String[] mobile2={"13811071500","13811071505","13811071502","13811071506","13811071504"};
        String[] mobile3=compareArray(mobile1,mobile2);
        for(int i=0;i<mobile3.length;i++)
            System.out.println(mobile3[i]);
    }
    public static String[] compareArray(String[]A,String[]B){
        Hashtable<String,String> hash = new Hashtable<String, String>();
        Hashtable<String,String> hash_new = new Hashtable<String, String>();
        for (int i = 0; i < B.length; i++){
            hash.put(B[i],B[i]);
        }
        for (int i = 0 ; i < B.length ; i++) {
            if (!hash.containsKey(A[i])) {
                hash_new.put(A[i], A[i]);
            }
        }
            String[] C = new String[hash_new.size()];
            int j = 0;
            Enumeration enumeration =   hash_new.keys();
            while (enumeration.hasMoreElements()) {
                C[j] = enumeration.nextElement().toString();
                j++;
            }
        return C;
    }
}

執行結果:
執行結果
可能會有人想好像兩個例子的輸出結果都是逆序的,實則不然,我們可以回到hashtable表的原始碼中去看一看就知道了hashtable其實是無序的,逆序輸出只不過是表面現象,你多加些資料再試一試就會發現不一樣了。
在開發中其實用的更多的就是hashtable,在我們個人學習中可能用hashmap更多一些吧。