C#实现自定义Dictionary类实例
作者:北风其凉 发布时间:2022-12-19 09:23:47
标签:C#,自定义,Dictionary
本文实例讲述了C#实现自定义Dictionary类。分享给大家供大家参考。具体如下:
1.关于MyDictionary类
本文中实现的MyDictionary类具有如下功能
1)可以增加、修改、删除键值对
2)可以通过索引器,找到一个键对应的值
3)可以遍历打印类中全部的键值对
4)可以将类中的序列转化为有序的(不排序、升序、降序)List类型
MyDictionary类是一个具有两个参数的泛型类,内部机制采用以键值对(KeyValuePair)类型为元素的双向链表(LinkedList)实现
2.实现代码
class MyDictioinary<TKey, TValue>
{
LinkedList<KeyValuePair<TKey, TValue>> llDictionary
= new LinkedList<KeyValuePair<TKey, TValue>>();
/// <summary>
/// 索引器,输入TKey可以找到对应的TValue
/// </summary>
/// <param name="tk">键值</param>
/// <returns></returns>
public TValue this[TKey tk]
{
get
{
foreach(KeyValuePair<TKey, TValue> kvp in llDictionary)
{
if (tk.Equals(kvp.Key))
{
return kvp.Value;
}
}
return default(TValue);
}
}
/// <summary>
/// 添加一组数据
/// </summary>
/// <param name="tk"></param>
/// <param name="tv"></param>
public void Add(TKey tk, TValue tv)
{
foreach (KeyValuePair<TKey, TValue> kvp in llDictionary)
{
if (tk.Equals(kvp.Key))
{
throw new Exception("新增失败:主键已经存在");
}
}
llDictionary.AddLast(new KeyValuePair<TKey, TValue>(tk, tv));
}
/// <summary>
/// 删除一组数据
/// </summary>
/// <param name="tk"></param>
public void Delete(TKey tk)
{
foreach (KeyValuePair<TKey, TValue> kvp in llDictionary)
{
if (tk.Equals(kvp.Key))
{
llDictionary.Remove(kvp);
return;
}
}
throw new Exception("删除失败:不存在这个主键");
}
/// <summary>
/// 修改一组数据
/// </summary>
/// <param name="tk"></param>
/// <param name="tv"></param>
public void Modify(TKey tk, TValue tv)
{
LinkedListNode<KeyValuePair<TKey, TValue>> lln = llDictionary.First;
while (lln != null )
{
if (tk.Equals(lln.Value.Key))
{
llDictionary.AddBefore(lln, new KeyValuePair<TKey, TValue>(tk, tv));
llDictionary.Remove(lln);
return;
}
lln = lln.Next;
}
throw new Exception("修改失败:不存在这个主键");
}
/// <summary>
/// 打印整个Dictionary内的全部数据
/// </summary>
public void PrintData()
{
Console.WriteLine("==================");
Console.WriteLine("输出数据");
Console.WriteLine("==================");
foreach (KeyValuePair<TKey, TValue> kvp in llDictionary)
{
Console.WriteLine(kvp.Key.ToString() + "\t:" + kvp.Value.ToString());
}
Console.WriteLine(string.Format("共计输出 {0} 项", llDictionary.Count));
Console.WriteLine(DateTime.Now.ToLongTimeString());
Console.WriteLine("==================");
}
/// <summary>
/// 决定按什么顺序打印Dictionary内的数据
/// </summary>
public enum PrintType
{
Normal = 0, //不排序
Ascend = 1, //升序排列
Descend = 2 //降序佩列
};
/// <summary>
/// 返回List类型的数据
/// </summary>
/// <param name="printType">List内数据的排序情况</param>
/// <returns></returns>
public List<KeyValuePair<TKey, TValue>> ToList(PrintType printType = PrintType.Normal)
{
switch (printType)
{
case PrintType.Normal:
{
return llDictionary.ToList();
}
case PrintType.Ascend:
{
if (llDictionary.Count == 0) return null;
LinkedList<KeyValuePair<TKey, TValue>> newll =
new LinkedList<KeyValuePair<TKey, TValue>>();
try
{
LinkedListNode<KeyValuePair<TKey, TValue>> lln = llDictionary.First;
while (lln != null)
{
LinkedListNode<KeyValuePair<TKey, TValue>> lln2 = newll.First;
while (lln2 != null)
{
//Key是字符串的情况
if (llDictionary.First.Value.Key.GetType() ==
"string".GetType())
{
if (string.Compare(lln2.Value.Key.ToString(),
lln.Value.Key.ToString()) > 0)
{
newll.AddBefore(lln2, new LinkedListNode
<KeyValuePair<TKey, TValue>>(lln.Value));
break;
}
}
else //Key可以被转化为浮点数的情况
{
if (double.Parse(lln2.Value.Key.ToString()) >
double.Parse(lln.Value.Key.ToString()))
{
newll.AddBefore(lln2, new LinkedListNode
<KeyValuePair<TKey, TValue>>(lln.Value));
break;
}
}
lln2 = lln2.Next;
}
if (lln2 == null)
{
newll.AddLast(new LinkedListNode
<KeyValuePair<TKey, TValue>>(lln.Value));
}
lln = lln.Next;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return newll.ToList();
}
case PrintType.Descend:
{
if (llDictionary.Count == 0) return null;
LinkedList<KeyValuePair<TKey, TValue>> newll =
new LinkedList<KeyValuePair<TKey, TValue>>();
try
{
LinkedListNode<KeyValuePair<TKey, TValue>> lln = llDictionary.First;
while (lln != null)
{
LinkedListNode<KeyValuePair<TKey, TValue>> lln2 = newll.First;
while (lln2 != null)
{
//Key是字符串的情况
if (llDictionary.First.Value.Key.GetType() ==
"string".GetType())
{
if (string.Compare(lln2.Value.Key.ToString(),
lln.Value.Key.ToString()) < 0)
{
newll.AddBefore(lln2, new LinkedListNode
<KeyValuePair<TKey, TValue>>(lln.Value));
break;
}
}
else //Key可以被转化为浮点数的情况
{
if (double.Parse(lln2.Value.Key.ToString()) <
double.Parse(lln.Value.Key.ToString()))
{
newll.AddBefore(lln2, new LinkedListNode
<KeyValuePair<TKey, TValue>>(lln.Value));
break;
}
}
lln2 = lln2.Next;
}
if (lln2 == null)
{
newll.AddLast(new LinkedListNode
<KeyValuePair<TKey, TValue>>(lln.Value));
}
lln = lln.Next;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return newll.ToList();
}
default: return null;
}
}
}
3.Main函数调用示例
static void Main(string[] args)
{
MyDictioinary<string, string> dic = new MyDictioinary<string, string>();
//插入两组数据
dic.Add("1", "MERCURY");
dic.Add("2", "VENUS");
//尝试插入重复主键的数据 报警:主键不存在
try
{
dic.Add("1", "EARTH");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
//删除一组数据
dic.Delete("1");
//添加一组数据
dic.Add("1", "MARS");
//修改两组数据
dic.Modify("1", "JUPITER");
dic.Modify("2", "SATURN");
//添加两组数据
dic.Add("6", "SUN");
dic.Add("5", "MOON");
dic.Add("8", "URANUS");
dic.Add("9", "NEPTUNE");
dic.PrintData();
//通过索引找到对应值
Console.WriteLine("key为6的元素value为:" + dic["6"]);
Console.WriteLine("key为3的元素value为:" + dic["3"]);
List<KeyValuePair<string, string>> l;
//输出升序排列好的List
l = dic.ToList(MyDictioinary<string, string>.PrintType.Ascend);
Console.WriteLine("升序排列后的List:");
for (int i = 0; i < l.Count; i++)
{
Console.WriteLine(l[i].Key.ToString() + "\t:" + l[i].Value.ToString());
}
//输出降序排列好的List
l = dic.ToList(MyDictioinary<string, string>.PrintType.Descend);
Console.WriteLine("降排列后的List:");
for (int i = 0; i < l.Count; i++)
{
Console.WriteLine(l[i].Key.ToString() + "\t:" + l[i].Value.ToString());
}
Console.ReadLine();
}
4.运行示例
希望本文所述对大家的C#程序设计有所帮助。
0
投稿
猜你喜欢
- 一般情况下,我们大部分人都是在XML文件直接写布局,可是有些时候需要用代码动态添加布局,比如我昨天做一个viewpager的页数
- 本文实例讲述了android动态布局之动态加入TextView和ListView的方法。分享给大家供大家参考。具体实现方法如下:packag
- 实例如下:func exitApplication() { let app = UIApplication.sh
- 第一步:添加新项目第二步:添加新的页签,注意,此页签是显示到Outlook主界面的第三步:添加自己想要的文本框以及按钮第四步:如果你想将此界
- 网上的文章基本上都是只有多数据源或只有动态数据源,而最近的项目需要同时使用两种方式,记录一下配置方法供大家参考。应用场景项目需要同时连接两个
- 使用DOM4J方式生成XML文件的步骤如下:引入JAR包通过DocumentHelper类的createDocument()创建Docume
- 个人理解:把一个类里的多个命令分离出来,每个类里放一个命令,实现解耦合,一个类只对应一个功能,在使用命令时由另一个类来统一管理所有命令。缺点
- 写在前面本文由markdown格式写成,为本人第一次这么写,排版可能会有点乱,还望各位海涵。 主要写的是使用Ribbon进行Res
- 添加注解效果事务演示注解我们经常会用到,或者在jdk源码中也会看到,例如: @Deprecated以及我们在spring或者spr
- //测试StringBuilder的运行效率 publi
- mkdir函数用于创建目录。格式如下:#include<sys/types.h>#include<sys/stat.h&g
- 引言相信大家在生活中,特别是最近的双十一活动期间,会收到很多短信,而那些短信都有两个特征,第一个是几乎都是垃圾短信,这个特点此处可以忽略不计
- 星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。
- 1.@RequestMapping注解1.1@RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping
- 一条SQL使用两个foreach的问题未修改前的 SQL 语句<select id="findQuestionType_3_
- Java super关键字super 关键字与 this 类似,this 用来表示当前类的实例,super 用来表示父类。super 可以用
- 1.委托delegate委托delegate也是一种类型,在任何可以声明类的地方都可以声明委托,它将方法当做另一个方法的参数进行传递,这样就
- 本文实例讲述了Java 8新增的方法参数反射。分享给大家供大家参考,具体如下:一 点睛Java 8在java.lang.reflect包下新
- tasks下面的代码展示了三个Gradle task,稍后会讲解这三者的不同。 task myTask { println "He
- clone() 方法麻烦一些,需要将所有涉及到的类实现声明式接口 Cloneable,并覆盖Object类中的clone()方法,并设置作用