5.简单数据结构类-Hashtable
5.1 知识点
Hashtable的本质
Hashtable(又称散列表)是基于键的哈希代码组织起来的键/值对,其主要作用是提高数据查询的效率。使用键来访问集合中的元素。
Hashtable的申明
需要引用命名空间 System.Collections
。
Hashtable hashtable = new Hashtable();
Hashtable的增删查改和遍历
增
当前hashtable
中的元素有:
{}
Add方法:传入键和值。
hashtable.Add(1, "123");
hashtable.Add("123", 2);
hashtable.Add(true, false);
hashtable.Add(false, false);
// 注意:不能出现相同键
// hashtable.Add(1, "123");// 报错,不能出现相同键
增完之后hashtable
中的元素有:
{
键:123 值:2
键:False 值:False
键:1 值:"123"
键:True 值:False
}
删
当前hashtable
中的元素有:
{
键:123 值:2
键:False 值:False
键:1 值:"123"
键:True 值:False
}
Remove方法:传入键,只能通过键去删除。
hashtable.Remove(1);
// 要是删除不存在的键的话,没有反应
hashtable.Remove(2);
Clear方法:直接清空。
// hashtable.Clear(); // 会清空哈希表,为后面方便演示,注释
删完之后hashtable
中的元素有:
{
键:123 值:2
键:False 值:False
键:True 值:False
}
查
当前hashtable
中的元素有:
{
键:123 值:2
键:False 值:False
键:True 值:False
}
Hashtable[key]索引器get:通过键查看值。
Console.WriteLine(hashtable["123"]); // 2
// 找不到会返回空
Console.WriteLine(hashtable[4]); // null
Console.WriteLine(hashtable["123123"]); // null
Contains方法、ContainsKey方法:传入键,查看键是否存在于哈希表中。存在返回true
,否则返回false
。
// 根据键检测
if (hashtable.Contains("123"))
{
Console.WriteLine("存在键为123的键值对"); // 存在键为123的键值对
}
if (hashtable.ContainsKey(2))
{
Console.WriteLine("存在键为2的键值对");
}
ContainsValue方法:传入值,查看值是否存在于哈希表中。存在返回true
,否则返回false
。
// 根据值检测
if (hashtable.ContainsValue(2))
{
Console.WriteLine("存在值为2的键值对"); // 存在值为2的键值对
}
改
当前hashtable
中的元素有:
{
键:123 值:2
键:False 值:False
键:True 值:False
}
Hashtable[key]索引器set:通过键修改值。
// 只能改变键对应的值内容,无法修改键
Console.WriteLine(hashtable[false]); // False 传键时不能输入大写False,输入小写的false
hashtable[false] = 100.5f;
Console.WriteLine(hashtable[false]); // 100.5f
改完之后hashtable
中的元素有:
{
键:123 值:2
键:False 值:100.5f
键:True 值:False
}
遍历
当前hashtable
中的元素有:
{
键:123 值:2
键:False 值:100.5f
键:True 值:False
}
Count属性:返回键值对数量。
Console.WriteLine(hashtable.Count); // 3
foreach遍历所有键:Hashtable.Keys
得到所有键。
foreach (object item in hashtable.Keys)
{
Console.WriteLine("键:" + item);
Console.WriteLine("值:" + hashtable[item]);
// 打印如下,无序
//{
// 键:123 值:2
// 键:False 值:100.5f
// 键:True 值:False
//}
}
foreach遍历所有值:Hashtable.Values
得到所有值。
foreach (object item in hashtable.Values)
{
Console.WriteLine("值:" + item);
// 打印如下,无序
//{
// 值:2
// 值:100.5f
// 值:False
//}
}
foreach遍历键值对:
// DictionaryEntry和迭代器相关,是一个数据结构,里面存了一个键和一个值
// item.Key得到当前键,item.Value得到当前值
foreach (DictionaryEntry item in hashtable)
{
Console.WriteLine("键:" + item.Key + " 值:" + item.Value);
// 打印如下,无序
//{
// 键:123 值:2
// 键:False 值:100.5f
// 键:True 值:False
//}
}
迭代器遍历法:
通过Hashtable
的GetEnumerator
方法获得一个IDictionaryEnumerator
字典枚举器接口对象。IDictionaryEnumerator
字典枚举器接口有Key
和Value
。
IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator();
// IDictionaryEnumerator接口里的MoveNext方法相当于一个游标,只要后面还有键值对会返回true
bool flag = myEnumerator.MoveNext();
// while循环遍历哈希表
while (flag)
{
// 打印IDictionaryEnumerator字典枚举器接口的Key和Value
Console.WriteLine("IDictionaryEnumerator 键:" + myEnumerator.Key + " IDictionaryEnumerator 值:" + myEnumerator.Value);
// 通过MoveNext方法判断后面还有没有键值对
flag = myEnumerator.MoveNext();
// 打印如下,无序
//{
// IDictionaryEnumerator 键:True IDictionaryEnumerator 值:False
// IDictionaryEnumerator 键:False IDictionaryEnumerator 值:100.5
// IDictionaryEnumerator 键:123 IDictionaryEnumerator 值:2
//}
}
Hashtable的装箱拆箱
由于用object
来存储数据,自然存在装箱拆箱。当往其中进行值类型存储时就是在装箱,当将值类型对象取出来转换使用时,就存在拆箱。
5.2 知识点代码
using System;
using System.Collections;
namespace Lesson4_Hashtable
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hashtable");
#region 知识点一 Hashtalbe的本质
//Hashtable(又称散列表) 是基于键的哈希代码组织起来的 键/值对
//它的主要作用是提高数据查询的效率
//使用键来访问集合中的元素
#endregion
#region 知识点二 Hashtalbe的申明
//需要引用命名空间 System.Collections
Hashtable hashtable = new Hashtable();
#endregion
#region 知识点三 Hashtalbe的增删查改和遍历
#region 增
//当前hashtable中的元素有
//{}
//Add方法 传入键和值
hashtable.Add(1, "123");
hashtable.Add("123", 2);
hashtable.Add(true, false);
hashtable.Add(false, false);
//注意:不能出现相同键
//hashtable.Add(1, "123");//报错 不能出现相同键
//增完之后hashtable中的元素有
//{
//键:123 值:2
//键:False 值:False
//键:1 值:123
//键:True 值:False
//}
#endregion
#region 删
//当前hashtable中的元素有
//{
//键:123 值:2
//键:False 值:False
//键:1 值:123
//键:True 值:False
//}
//1.Remove方法 传入键 只能通过键去删除
hashtable.Remove(1);
//要是删除不存在的键的话 没反应
hashtable.Remove(2);
//2.Clear方法 直接清空
//hashtable.Clear();//会清空哈希表 为后面方便演示 注释
//删完之后hashtable中的元素有
//{
//键:123 值:2
//键:False 值:False
//键:True 值:False
//}
#endregion
#region 查
//当前hashtable中的元素有
//{
//键:123 值:2
//键:False 值:False
//键:True 值:False
//}
//Hashtable[key] 通过键查看值
Console.WriteLine(hashtable["123"]);//2
//找不到会返回空
Console.WriteLine(hashtable[4]);//null
Console.WriteLine(hashtable["123123"]);//null
//Contains方法 ContainsKeys方法 传入键 查看键是否存在于哈希表中 存在返回true 否则返回false
//根据键检测
if (hashtable.Contains("123"))
{
Console.WriteLine("存在键为123的键值对");//存在键为123的键值对
}
if (hashtable.ContainsKey(2))
{
Console.WriteLine("存在键为2的键值对");
}
//ContainsValue方法 传入值 查看值是否存在于哈希表中 存在返回true 否则返回false
//根据值检测
if (hashtable.ContainsValue(2))
{
Console.WriteLine("存在值为2的键值对");//存在值为2的键值对
}
#endregion
#region 改
//当前hashtable中的元素有
//{
//键:123 值:2
//键:False 值:False
//键:True 值:False
//}
//Hashtable[key] 通过键修改值
//只能改 键对应的值内容 无法修改键
Console.WriteLine(hashtable[false]);//False 传键时不能输入大写False 输入小写的false
hashtable[false] = 100.5f;
Console.WriteLine(hashtable[false]);//100.5f
//改完之后hashtable中的元素有
//{
//键:123 值:2
//键:False 值:100.5f
//键:True 值:False
//}
#endregion
#region 遍历
//当前hashtable中的元素有
//{
//键:123 值:2
//键:False 值:100.5f
//键:True 值:False
//}
//Count属性 返回键值对 对数
Console.WriteLine(hashtable.Count);//3
//foreach遍历所有键 Hashtable.Keys得到所有键
foreach (object item in hashtable.Keys)
{
Console.WriteLine("键:" + item);
Console.WriteLine("值:" + hashtable[item]);
//打印如下 无序
//{
//键:123 值:2
//键:False 值:100.5f
//键:True 值:False
//}
}
//foreach遍历所有值 Hashtable.Values得到所有值
foreach (object item in hashtable.Values)
{
Console.WriteLine("值:" + item);
//打印如下 无序
//{
//值:2
//值:100.5f
//值:False
//}
}
//foreach遍历键值对
//DictionaryEntry和迭代器相关 是一个数据结构 里面存了一个键一个值
//item.Key得到当前键 item.Value得到当前值
foreach (DictionaryEntry item in hashtable)
{
Console.WriteLine("键:" + item.Key + "值:" + item.Value);
//打印如下 无序
//{
//键:123 值:2
//键:False 值:100.5f
//键:True 值:False
//}
}
//迭代器遍历法
//通过Hashtable的GetEnumerator方法获得一个IDictionaryEnumerator字典枚举器接口对象
//IDictionaryEnumerator字典枚举器接口有Key和Value
IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator();
//IDictionaryEnumerator接口里的MoveNext方法相当于一个游标 只要后面还有键值对会返回true
bool flag = myEnumerator.MoveNext();
//while循环遍历哈希表
while (flag)
{
//打印IDictionaryEnumerator字典枚举器接口的Key和Value
Console.WriteLine("IDictionaryEnumerator键:" + myEnumerator.Key + "IDictionaryEnumerator值:" + myEnumerator.Value);
//通过MoveNext方法判断后面还有没有键值对
flag = myEnumerator.MoveNext();
//打印如下 无序
//{
//IDictionaryEnumerator键:TrueIDictionaryEnumerator值:False
//IDictionaryEnumerator键:FalseIDictionaryEnumerator值:100.5
//IDictionaryEnumerator键:123IDictionaryEnumerator值:2
//}
}
#endregion
#endregion
#region 知识点四 Hashtable的装箱拆箱
//由于用万物之父来存储数据,自然存在装箱拆箱
//当往其中进行值类型存储时就是在装箱
//当将值类型对象取出来转换使用时,就存在拆箱
#endregion
}
}
}
5.3 练习题
请描述Hashtable的存储规则
- Hashtable是一种键值对形式存储的容器。
- 每个键对应一个值,其中键和值的类型都是
object
。 - Hashtable的键是唯一的,即不能重复。
制作一个怪物管理器,提供创建怪物,移除怪物的方法。每个怪物都有自己的唯一ID
class语句块外 namespace语句块内
/// <summary>
/// 怪物管理器类,因为一般管理器都是唯一的,所以把它做成一个单例模式的对象
/// </summary>
class MonsterMgr
{
// 怪物管理器单例 初始化new出来
private static MonsterMgr instance = new MonsterMgr();
// 怪物管理器单例 提供给外部使用 得到唯一的怪物管理器 第一次使用的时候会new出来
public static MonsterMgr Instance
{
get
{
return instance;
}
}
// 私有的怪物管理器构造函数 外面new不出来
private MonsterMgr()
{
}
// 怪物哈希表
private Hashtable monstersTable = new Hashtable();
// 怪物id默认是0
private int monsterID = 0;
// 添加怪物
public void AddMonster()
{
// 添加怪物时创建怪物
Monster monster = new Monster(monsterID);
Console.WriteLine("创建了id为{0}的怪物", monsterID);
// 怪物id+1
++monsterID;
// 存到怪物哈希表中
// Hashtable的键是不能重复的,所以一定是用唯一ID
monstersTable.Add(monster.id, monster);
}
// 移除怪物
public void RemoveMonster(int monsterID)
{
// 判断怪物哈希表中有没有这个怪物id
if (monstersTable.ContainsKey(monsterID))
{
// 有的话调用怪物死亡
(monstersTable[monsterID] as Monster).Dead();
// 怪物哈希表中移除
monstersTable.Remove(monsterID);
}
}
}
// 怪物类
class Monster
{
// 怪物唯一id
public int id;
// 怪物构造函数 初始化怪物
public Monster(int id)
{
this.id = id;
}
// 怪物死亡
public void Dead()
{
Console.WriteLine("怪物{0}死亡", id);
}
}
主函数内
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
// 创建了id为0的怪物
// 创建了id为1的怪物
// 创建了id为2的怪物
// 创建了id为3的怪物
// 创建了id为4的怪物
// 创建了id为5的怪物
MonsterMgr.Instance.RemoveMonster(0);
MonsterMgr.Instance.RemoveMonster(3);
// 怪物0死亡
// 怪物3死亡
5.4 练习题代码
using System;
using System.Collections;
namespace Lesson4_练习题
{
#region 练习题一
//请描述Hashtable的存储规则
// 一个键值对形式存储的 容器
// 一个键 对应一个值
// 类型是object
#endregion
//class语句块外 namespace语句块内
#region 练习题二
//制作一个怪物管理器,提供创建怪物
//移除怪物的方法。每个怪物都有自己的唯一ID
/// <summary>
/// 怪物管理器类 因为一般 管理器 都是唯一的 所以把它做成 一个单例模式的对象
/// </summary>
class MonsterMgr
{
//怪物管理器单例 初始化new出来
private static MonsterMgr instance = new MonsterMgr();
//怪物管理器单例 提供给外部使用 得到唯一的怪物管理器 第一次使用的时候会new出来
public static MonsterMgr Instance
{
get
{
return instance;
}
}
//私有的怪物管理器构造函数 外面new不出来
private MonsterMgr()
{
}
//怪物哈希表
private Hashtable monstersTable = new Hashtable();
//怪物id默认是0
private int monsterID = 0;
//添加怪物
public void AddMonster()
{
//添加怪物时创建怪物
Monster monster = new Monster(monsterID);
Console.WriteLine("创建了id为{0}的怪物", monsterID);
//怪物id+1
++monsterID;
//存到怪物哈希表中
//Hashtable 的键 是不能重复的 所以一定是用唯一ID
monstersTable.Add(monster.id, monster);
}
//移除怪物
public void RemoveMonster(int monsterID)
{
//判断怪物哈希表中有没有这个怪物id
if (monstersTable.ContainsKey(monsterID))
{
//有的话调用怪物死亡
(monstersTable[monsterID] as Monster).Dead();
//怪物哈希表中移除
monstersTable.Remove(monsterID);
}
}
}
//怪物类
class Monster
{
//怪物唯一id
public int id;
//怪物构造函数 初始化怪物
public Monster(int id)
{
this.id = id;
}
//怪物死亡
public void Dead()
{
Console.WriteLine("怪物{0}死亡", id);
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hashtable练习题");
//主函数内
#region 练习题二
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
//创建了id为0的怪物
//创建了id为1的怪物
//创建了id为2的怪物
//创建了id为3的怪物
//创建了id为4的怪物
//创建了id为5的怪物
MonsterMgr.Instance.RemoveMonster(0);
MonsterMgr.Instance.RemoveMonster(3);
//怪物0死亡
//怪物3死亡
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com