19.3.2 通过实例熟悉散列表如何存储数据

在举实例之前,先介绍散列表的构造器和常用的方法。只有了解这些方法,才能更好地应用散列表来存储数据。

散列表的构造器代码如下所示:

❑Hashtable()

构建一个空的散列表,初始容量为11。负载因子为0.75。

❑Hashtable(int initalCapacity, float loadFactor)

指定初始化容量和负载因子,构造一个散列表。

❑Hashtable(Map t)

根据映像所包含的元素,构建一个散列表。

散列表的主要方法:

❑object put(object key, object vaule):put方法是向一个散列表中添加元素。由于在散列表中是根据所添加元素的键值来定位元素,这个键值是唯一的。针对这个方法,务必要记住这个键值一定是对象型数据。

❑boolean containskey(object key)和boolean containvalue(object value):这两个方法是测试散列表中是否包含指定的键值和值。

❑Object remove(object key):根据指定的键值从散列表中删除对应键的元素。

❑Collection values():返回散列表中所包含元素的集合,是元素的集合,而不是key的集合。

【实例19.4】下面将针对上面的方法和构造器,演示一个有关散列表的实例。实例的流程如图19.8所示。


先设计一个教师类,然后,在主运行类中创建教师类的对象和散列表对象,并将教师类对象装载到散列表对象中,最后在主运行类中操作散列表中的元素。这里没有使用到迭代器,因为散列表中的元素不像链表或数组列表中一样有序。实例的主要代码如下:

19.3.2 通过实例熟悉散列表如何存储数据 - 图1

图 19.8 散列表数据结构的实例

(1)教师类的设计代码。


01 ///创建一个教师类

02 ///schoolname指学校 名称

03 ///classname指 班级名称

04 ///teachername指老师姓名

05 ///teachercode指老师工号

06 ///teachersexy指 性别

07 ///teacherbirthday指出 生年月

08 ///familyaddress指 家庭地址

09 ///set是设置器

10 ///get是访问器

11 ///tostring方法是使得对象能够以字符串形式输出的方法

12 class teacher

13 {

14 private String schoolname;

15 private String classname;

16 private String teachername;

17 private String teachercode;

18 private String teachersexy;

19 private String teacherbirthday;

20 private String familyaddress;

21 public teacher(String teachername, String teachercode, String teachersexy, String

22 teacherbirthday)

23 {

24 this.teachername=teachername;

25 this.teachercode=teachercode;

26 this.teachersexy=teachersexy;

27 this.teacherbirthday=teacherbirthday;

28 }

29 public String getname()

30 {

31 return teachername;

32 }

33 public String getcode()

34 {

35 return teachercode;

36 }

37 public String getsexy()

38 {

39 return teachersexy;

40 }

41 public String getbirthday()

42 {

43 return teacherbirthday;

44 }

45 public void setschoolname(String schoolname)

46 {

47 this.schoolname=schoolname;

48 }

49 public void setclassname(String classname)

50 {

51 this.classname=classname;

52 }

53 54

public void setfamilyaddress(String familyaddress)

55 {

56 this.familyaddress=familyaddress;

57 }

58 public String getschoolname()

59 {

60 return schoolname;

61 }

62 public String getclassname()

63 {

64 return classname;

65 }

66 public String getfamilyaddress()

67 {

68 return familyaddress;

69 }

70 public String toString()

71 {

72 String infor="学校 名称:"+schoolname+""+" 班级名称:"+classname+""+" 教师姓名:

73"+teachername+""+" 教师工号:"+teachercode+""+" 性别:"+teachersexy+""+"出 生年月:

74"+teacherbirthday+""+" 家庭地址:"+familyaddress;

75 return infor;

76 }

77 }


(2)主运行类中,在不使用迭代器对象的情况下,操作散列表中数据。


78 import java.util.Hashtable;

79 ///主运行类

80 ///ht是创建的一个哈希表对象

81 ///t1至t6是针对教师类创建出来的六个对象

82 ///set设置器赋值给这六个对象

83 ///put方法是散列表中添加元素的方法

84 ///remove方法是散列表中删除元素的方法

85 public class test2

86 {

87 public static void main(String[]args)

88 {

89 Hashtable ht=new Hashtable();

90 teacher t1=new teacher("赵浩","1234001","男","1981-01-02");

91 teacher t2=new teacher("黎平","1234002","男","1982-08-09");

92 teacher t3=new teacher("王鹏","1234003","男","1982-11-22");

93 teacher t4=new teacher("宋波","1234004","女","1982-11-02");

94 teacher t5=new teacher("章伟","1234005","男","1980-01-12");

95 teacher t6=new teacher("孙君","1234006","女","1981-09-22");

96 t1.setschoolname("重庆大学");

97 t1.setclassname("计算机三班");

98 t1.setfamilyaddress("重庆沙坪坝");

99 t2.setschoolname("重庆大学");

100 t2.setclassname("计算机三班");

101 t2.setfamilyaddress("重庆沙坪坝");

102 t3.setschoolname("重庆大学");

103 t3.setclassname("计算机三班");

104 t3.setfamilyaddress("重庆沙坪坝");

105 t4.setschoolname("重庆大学");

106 t4.setclassname("计算机三班");

107 t4.setfamilyaddress("重庆沙坪坝");

108 t5.setschoolname("重庆大学");

109 t5.setclassname("计算机三班");

110 t5.setfamilyaddress("重庆沙坪坝");

111 t6.setschoolname("重庆大学");

112 t6.setclassname("计算机三班");

113 t6.setfamilyaddress("重庆沙坪坝");

114 teacher t=new teacher("孟凡良","34512","男","1954-09-23");

115 t.setschoolname("成都科技大学");

116 t.setclassname("机械系三班");

117 t.setfamilyaddress("成都市区");

118 ht.put("zh",t1);//在哈希表中添加元素

119 ht.put("lp",t2);

120 ht.put("wp",t3);

121 ht.put("sb",t4);

122 ht.put("zw",t5);

123 ht.put("sj",t6);

124 System.out.println("这个小组有"+ht.size()+"个教师。");

125 //输出哈希表中元素个数

126 System.out.println(ht.values());

127 System.out.println("我需要查找一个教师的信息。");

128 //输出哈希表中的元素内容

129 if(ht.containsKey("wh"))

130 {

131 System.out.println("找到了此教师的信息,如下:");

132 System.out.println((teacher)ht.get("ww"));

133 }

134 else

135 {

136 System.out.println("没有找到此教师的信息!");

137 }

138 ht.remove("lp");//删除哈希表中的元素

139 ht.remove("sj");

140 System.out.println("由于有些教师离开了学校,经过我们的审核后,教师信息如下:");

141 System.out.println(ht.values());//输出哈希表中剩下的元素内容

142 }

143 }


【代码说明】分析以上的程序段,发现其与前面介绍的链表和数组列表有些不同。首先不可以通过迭代器来对其进行访问,因为它是无序的。另外访问它时,最关键的就是键值。

散列表主要是通过键值进行一些散列值的计算,计算的结果作为这个对象的地址。所以对于拥有大量数据的数据库来说,使用散列表存储数据,比使用链表和数组列表会更方便。

注意 在散列表中,不允许有两个相同的元素,如有相同的元素,程序会将其作为一个元素来处理。

【运行效果】


这个小组有6个教师。

[学校 名称:重庆大学 班级名称:计算机三班 教师姓名:孙君 教师工号:1234006 性别:女出 生年月:1981-09-22 家庭地址:重庆沙坪坝,学校 名称:重庆大学 班级名称:计算机三班 教师姓名:章伟 教师工号:1234005 性别:男出 生年月:1980-01-12 家庭地址:重庆沙坪坝,学校 名称:重庆大学 班级名称:计算机三班 教师姓名:王鹏

 教师工号:1234003 性别:男出 生年月:1982-11-22 家庭地址:重庆沙坪坝,学校名

称:重庆大学 班级名称:计算机三班 教师姓名:黎平 教师工号:1234002 性别:男出 生年月:1982-08-09 家庭地址:重庆沙坪坝,学校 名称:重庆大学 班级名称:计算机三班 教师姓名:赵浩 教师工号:1234001 性别:男出 生年月:1981-01-02 家庭地址:重庆沙坪坝,学校 名称:重庆大学 班级名称:计算机三班 教师姓名:宋波教师

工号:1234004 性别:女出 生年月:1982-11-02 家庭地址:重庆沙坪坝]我需要查找一个教师的信息。

没有找到此教师的信息!

由于有些教师离开了学校,经过我们的审核后,教师信息如下:

[学校 名称:重庆大学 班级名称:计算机三班 教师姓名:章伟 教师工号:1234005 性别:男出 生年月:1980-01-12 家庭地址:重庆沙坪坝,学校 名称:重庆大学 班级名称:计算机三班 教师姓名:王鹏 教师工号:1234003 性别:男出 生年月:1982-11-22 家庭地址:重庆沙坪坝,学校 名称:重庆大学 班级名称:计算机三班 教师姓名:赵浩

 教师工号:1234001 性别:男出 生年月:1981-01-02 家庭地址:重庆沙坪坝,学校名

称:重庆大学 班级名称:计算机三班 教师姓名:宋波 教师工号:1234004 性别:女出 生年月:1982-11-02 家庭地址:重庆沙坪坝]