19.4.2 通过实例熟悉散列集如何存储数据

【实例19.5】本节将通过一个实例,熟悉散列集的用法。


说明 散列集可以采用迭代器进行遍历。散列集和散列表一样,都不能拥有相同的元素。

散列集通过内部散列码计算元素存储地址,这一点与散列表一样,只不过散列集没有键值。下面针对散列集的数据结构举一个实例。实例的流程如图19.9所示。

先设计一个教师类,然后,在主运行类中创建教师类的对象和散列集对象,并将教师类对象装载到散列集对象中,再在主运行类中操作散列集中的元素。这里又开始使用到迭代器,因为散列集中的元素像链表或数组列表一样,都继承Collection类。实例步骤如下:

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

图 19.9 散列集数据结构的实例

(1)设计教师类,代码如下所示。


01 import java.util.HashSet;

02 import java.util.Iterator;

03 ///创建一个教师类

04 ///schoolname指学校 名称

05 ///classname指 班级名称

06 ///teachername指老师姓名

07 ///teachercode指老师工号

08 ///teachersexy指 性别

09 ///teacherbirthday指出 生年月

10 ///familyaddress指 家庭地址

11 ///set是设置器

12 ///get是访问器

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

14 15 class teacher

16 {

17 private String schoolname;

18 private String classname;

19 private String teachername;

20 private String teachercode;

21 private String teachersexy;

22 private String teacherbirthday;

23 private String familyaddress;

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

25 teacherbirthday)

26 {

27 this.teachername=teachername;

28 this.teachercode=teachercode;

29 this.teachersexy=teachersexy;

30 this.teacherbirthday=teacherbirthday;

31 }

32 public String getname()

33 {

34 return teachername;

35 }

36 public String getcode()

37 {

38 return teachercode;

39 }

40 public String getsexy()

41 {

42 return teachersexy;

43 }

44 public String getbirthday()

45 {

46 return teacherbirthday;

47 }

48 public void setschoolname(String schoolname)

49 {

50 this.schoolname=schoolname;

51 }

52 public void setclassname(String classname)

53 {

54 this.classname=classname;

55 }

56 57

public void setfamilyaddress(String familyaddress)

58 {

59 this.familyaddress=familyaddress;

60 }

61 public String getschoolname()

62 {

63 return schoolname;

64 }

65 public String getclassname()

66 {

67 return classname;

68 }

69 public String getfamilyaddress()

70 {

71 return familyaddress;

72 }

73 public String toString()

74 {

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

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

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

78 return infor;

79 }

80 }


(2)在主运行类中,利用迭代器对象和散列集对象,实现对数据的操作。详细代码如下所示。


81 ///主运行类

82 ///hs是创建的一个散列集对象

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

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

85 ///add方法是散列集中添加元素的方法

86 ///remove方法是散列集中删除元素的方法

87 ///it是迭代器对象,用来在数据结构中确定元素位置

88 public class test3

89 {

90 public static void main(String[]args)

91 {

92 HashSet hs=new HashSet();//创建一个散列集对象

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

117 //通过设置器赋值给每个对象

118 hs.add(t1);//往散列集中添加元素

119 hs.add(t2);

120 hs.add(t3);

121 hs.add(t4);

122 hs.add(t5);

123 hs.add(t6);

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

125 //输出散列集中的元素个数

126 Iterator it=hs.iterator();//新建一个迭代器对象

127 while(it.hasNext())

128 {

129 System.out.println(it.next());

130 }

131 hs.remove(t3);//删除散列集中元素

132 hs.remove(t4);

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

134 Iterator it1=hs.iterator();//新建一个迭代器对象

135 while(it1.hasNext())

136 {

137 System.out.println(it1.next());

138 }

139 System.out.println("这些教师今天都离职了,所有教师信息都可以删除了!");

140 hs.remove(t1);//删除散列集中的元素

141 hs.remove(t2);

142 hs.remove(t5);

143 hs.remove(t6);

144 if(hs.isEmpty())

145 {

146 System.out.println("这里把教师信息都删除了。");

147 }

148 else

149 {

150 System.out.println("系统报错了!");

151 }

152 }

153 }


【代码说明】第92行创建一个散列集对象,第118~123行往散列集中添加教师对象。第126~130行使用迭代器输出对象。

【运行效果】


这个小组有6个教师。

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

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

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

学校 名称:重庆大学 班级名称:计算机三班 教师姓名:孙君 教师工号:1234006 性别:女出 生年月:1981-09-22 家庭地址:重庆沙坪坝

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

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

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

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

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

学校 名称:重庆大学 班级名称:计算机三班 教师姓名:孙君 教师工号:1234006 性别:女出 生年月:1981-09-22 家庭地址:重庆沙坪坝

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

这些教师今天都离职了,所有教师信息都可以删除了!这里把教师信息都删除了。


从上面的例子可以看出,散列集同前面的链表和数组列表,在编写代码时几乎一样。那么它们有什么区别呢?

【实例19.6】下面通过一个程序实例查看它们的区别。


01 import java.util.HashSet;

02 import java.util.LinkedList;

03 04 public class test4

05 {

06 public static void main(String[]args)

07 {

08 long time=0;

09 HashSet hs=new HashSet();

10 LinkedList ll=new LinkedList();

11 long starttime=System.currentTimeMillis();

12 for(int i=0;i<10000;i++)

13 {

14 hs.add(new Integer(i));

15 }

16 System.out.println(System.currentTimeMillis()-starttime);

17 for(int i=0;i<10000;i++)

18 {

19 ll.add(new Integer(i));

20 }

21 System.out.println(System.currentTimeMillis()-starttime);

22 }

23 }


【代码说明】从结果可以看出,使用散列集进行数据处理,比使用链表进行数据处理花费的时间更短。这样可以节约系统资源。在这个程序中,需要说明的是System.currentTimeMillis()方法,它显示系统当前的时间。使用System.currentTimeMillis()-starttime计算两个时间段的时间差,即处理数据所需要花费的时间。

【运行效果】


15 31


【实例19.7】下面再举一个实例,说明如何对数组列表与散列集进行比较。


01 import java.util.HashSet;

02 import java.util.ArrayList;

03 04 public class test5

05 {

06 public static void main(String[]args)

07 {

08 long time=0;

09 HashSet hs=new HashSet();

10 ArrayList al=new ArrayList();

11 long starttime=System.currentTimeMillis();

12 for(int i=0;i<10000;i++)

13 {

14 hs.add(new Integer(i));

15 }

16 System.out.println(System.currentTimeMillis()-starttime);

17 for(int i=0;i<10000;i++)

18 {

19 al.add(new Integer(i));

20 }

21 System.out.println(System.currentTimeMillis()-starttime);

22 }

23 }


【代码说明】从结果可以看出,使用散列集进行数据处理,系统花费的时间更短,比使用数组列表进行数据处理速度更快,这样可以节约系统资源。所以在处理大量数据的时候,通常使用散列集。

【运行效果】


16 18