[Java] About Hashtable

本文介绍哈希表的基本概念,包括哈希函数、碰撞处理及负载因子等,并通过一个Java实例展示如何使用Hashtable类进行学生信息的增删改查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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:[url]http://blog.yam.com/bluelanguage/article/8401664[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值