hashtable對字串的碰撞以及原始碼解析(非常適合新手理解hashtable)
阿新 • • 發佈:2019-01-23
首先我從網上摘抄了三個典型的例子,非常適合來介紹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更多一些吧。