[Java] About Hashtable

在一個有序或無序的線性串列中,要尋找一筆資料通常要透過特定的搜尋資料與比對方式
,如果資料量很大,花費在搜尋上的時間成本也就隨之增大。

hashing是一種鍵值與陣列索引的對應,我們透過特定的hashing函式,將指定的鍵值經過
運算而得到一個hashing code,這個hashing code就當作是陣列的索引,資料就儲存在這個
索引的位置中。

要得到hashing code的運算方式有很多種,像是中間平方法、除法、摺疊法等等,無論是
哪種方式,都有可能在兩種不同鍵值,卻得到相同hashing code的情況,這個時候稱之為碰
撞(collision),解決碰撞的方式也有許多種,最簡單的就是直接往hashing code所指向的位置之下一格作線性探測,直到找到空間為止,另外還有就是使用鏈結串列,當碰撞發生
時,就將新的元素以鏈結的方式加在同一個位置的後面(這也是Java中的Hashtable類別所採取的方式),影響hashing效能的因性之後稱之為load factor,它的計算方式是hash table中的元素除以可容納的空間大小,load factor越接近1,表示hash table中的元素越多,發生碰撞的機率也就越大。

無論如何,製作一個hash table是相當麻煩的,然而Java的Hashtable類別可以讓您無需注意這些細節,在不發生碰撞的狀況下,使用hash table可以一次運算就找到所要的資料,
然而這並不是沒有代價,因為使用hash table就是一種以空間換取時間的方式,使用Hashtable會耗用較多的記憶體,因為要預先空出一個夠大的空間來當作hashing code的對應空間。

如果您想瞭解更多有關於hash table的細節,可以參考資料結構方面的書籍,我們接下來
直接使用一個範例來示範Hashtable類別的使用:

import java.util.*;
import java.io.*;

class Student {

	private String number;
	private String name;
	private double score;

	public Student(String number, String name, double score) {
		this.number = number;
		this.name = name;
		this.score = score;
	}

	public String getNumber() {
		return number;
	}

	public String getName() {
		return name;
	}

	public double getScore() {
		return score;
	}
}

public class UseHashtable {
	
	public static void main(String[] args) {
		
		try {
			OpHashtable();
		}catch(IOException e) {
			System.out.println(e.toString());
		}
	}

	private static void OpHashtable() throws IOException {
		
		Hashtable table = new Hashtable();
		BufferedReader buf = new BufferedReader(
		new InputStreamReader(System.in));
		int select;
		String number, name;
		double score;
		Object val;
		Student student;

		System.out.println("使用Hashtable類別");
		while(true) {
				System.out.println("(1) 加入學生資料");
				System.out.println("(2) 查詢學生資料");
				System.out.println("(3) 移除學生資料");
				System.out.println("(4) 列出所有資料");
				System.out.println("(5) 離開");
				System.out.print("> ");
				select = Integer.parseInt(buf.readLine());

				switch(select) {
				
					case 1:
						System.out.print("學號: ");
						number = buf.readLine();
						System.out.print("姓名: ");
						name = buf.readLine();
						System.out.print("成績: ");
						score = Double.parseDouble(buf.readLine());
						student = new Student(number, name, score);
						val = table.put(number, student);

						if(val == null)
							System.out.println("資料存入....");
						else
							System.out.println("資料取代....");
						break;
					
					case 2:
						System.out.print("學號: ");
						number = buf.readLine();
						student = (Student) table.get(number);
						if(student != null)
							System.out.println("學號: " + student.getNumber() +
											   "姓名: " + student.getName() +
											   "成績: " + student.getScore());
						else
							System.out.println("查無此筆資料....");
						break;

					case 3:
						System.out.print("學號: ");
						number = buf.readLine();
						val = table.remove(number);
						if(val != null)
							System.out.println("學生 " + number + " 資料移除");
						else
							System.out.println("查無此筆資料....");
						break;

					case 4:
						Enumeration enum = table.elements();
						while(enum.hasMoreElements()) {
							student = (Student) enum.nextElement();
							System.out.println("學號: " + student.getNumber() +
							"姓名: " + student.getName() +
							"成績: " + student.getScore());
						}
						break;
					
					case 5:
						default:
						System.exit(0);
				}
		}
	}
}


執行結果:
java UseHashtable


使用Hashtable類別
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 1
學號: B83503124
姓名: 米小狗
成績: 93.2
資料存入....
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 1
學號: B86550032
姓名: 毛小狗
成績: 94
資料存入....
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 2
學號: B83503124
學號: B83503124 姓名: 米小狗 成績: 93.2
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 4
學號: B86550032 姓名: 毛小狗 成績: 94.0
學號: B83503124 姓名: 米小狗 成績: 93.2
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 3
學號: Bee323
查無此筆資料....
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 3
學號: B86550032
學生 B86550032 資料移除
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 4
學號: B83503124 姓名: 米小狗 成績: 93.2
(1) 加入學生資料
(2) 查詢學生資料
(3) 移除學生資料
(4) 列出所有資料
(5) 離開
> 5

Hashtable類別的使用基本上是很簡單的,put()方法需要一個物件作為計算hashing code之用,而第二個參數是所要存入的物件,這兩個參數都必須給定,否則的話會發生NullPointerException例外,而如果之前同一位置已有物件,而在存入時所指定的鍵值相同時,則新物件會取代原位置的物件,而舊物件會被傳回,同樣的我們使用remove()方法時,也會傳回被移除的物件。

ref: http://blog.yam.com/bluelanguage/article/8401664

你可能感兴趣的:(java,Blog)