C#字典Dictionary的用法说明(注重性能版)

前言

以键值对Dictionary<[key], [value]>形式存值,和哈希表很像也是一种无序的结构。

要使用Dictionary,需要先导入C#泛型命名空间System.Collections.Generic

Dictionary需要注意的特性

1.任何键都必须是唯一的 ——> 不能添加相同key的键值对,不然就报错:

如果要修改已有key对应的value,可以这样做:

C#字典Dictionary的用法说明(注重性能版)_第1张图片

2.Unity5.4以下的版本,最好不要用foreach来遍历字典:

法一:foreach遍历字典,会生成GC:

C#字典Dictionary的用法说明(注重性能版)_第2张图片

C#字典Dictionary的用法说明(注重性能版)_第3张图片

法二:对于我这种需求,使用for循环,会生成更多的GC,因为存在mActMergeRedPointKey这个局部List变量

C#字典Dictionary的用法说明(注重性能版)_第4张图片

C#字典Dictionary的用法说明(注重性能版)_第5张图片

法三:使用迭代器,不会生成GC:

C#字典Dictionary的用法说明(注重性能版)_第6张图片

C#字典Dictionary的用法说明(注重性能版)_第7张图片

3.根据key取value,最好使用 TryGetValue 而不是 ContainsKey+根据key索引value:

法一:ContainsKey+根据key索引value,不好,用了两次查找,第一次:ContainsKey,第二次:myDictionary[key]

if(myDictionary.ContainsKey(key))
{
    // 通过key索引value
    int resValue = myDictionary[key];
}

法二:TryGetValue的方法:

int resValue ;
myDictionary.TryGetValue(key, out resValue);

使用TryGetValue更快,性能更好,因为只用了一次查找,TryGetValue 比 ContainsKey后使用[key]取value,速度快一倍;

TryGetValue更安全,找不到value时返回false;而使用ContainsKey后使用[key]取value取不到时,会抛出异常导致真机卡死。

用法

一般用法:key和value都为基本类型,举例:key为int类型,value为string类型

// 声明和初始化
Dictionary myDictionary = new Dictionary();
// 添加元素
myDictionary.Add(key,value);
// 判断是否包含键
if(myDictionary.ContainsKey(key))
// 总个数
myDictionary.Count
// 遍历
foreach(string key in myDictionary.Keys) // myDictionary.Keys:所有键的集合
{
    int resValue = myDictionary[key];
}
//调用成员Keys,会产生额外GC:Dictionary本身储存数据是成对储存的,也就是KeyValuePair,所以
//要单独拿出Keys时会新建一个数组,这也使得GC增加,推荐大家如果不需要单独存储Keys,尽量避免调用。
// 移除指定键和值
myDictionary.Remove(key);

实例应用

    private Dictionary myPets;
    public List GetShowPets()
    {
        List pets = new List();
        if (null != myPets)
        {
            var e = myPets.GetEnumerator();
            while (e.MoveNext())
            {
                if (CheckPetShow(e.Current.Key))
                {
                    pets.Add(e.Current.Value);
                }
            }
        }
        //根据配置表权重进行升序排序
        pets.Sort(
            delegate (MyPet pet1, MyPet pet2) 
            {
                return pet1.PetRankWeight.CompareTo(pet2.PetRankWeight);
            });
        return pets;
    }

补充:c#中字典类(Dictionary)介绍

关键字:Dictionary

说明:

1、必须包含命名空间System.Collection.Generic

2、Dictionary里面每一个元素都是以键值对的形式存在的

3、键必须是唯一的,而值不需要唯一的

4、键和值都可以以任何数据类型存在(比如:值类型、引用类型、自定义类型等等)

5、通过一个键读取一个值得时间接近O(1)

字典的使用方法:

定义:

Dictionary openWith = new Dictionary();
//添加元素
 openWith.Add("txt", "notepad.exe");
 openWith.Add("bmp", "paint.exe");
 openWith.Add("dib", "paint.exe");
 openWith.Add("rtf", "wordpad.exe");
 openWith["png"] = "picture.exe"
//取值
Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);
//更改值
openWith["rtf"] = "winword.exe";
Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);
 //遍历key
foreach (string key in openWith.Keys)
{
    Console.WriteLine("Key = {0}", key);
}
//遍历value
    foreach (string value in openWith.Values)
    {
        Console.WriteLine("value = {0}", value);
    }
 
    //遍历value, Second Method
    Dictionary.ValueCollection valueColl = openWith.Values;
    foreach (string s in valueColl)
    {
        Console.WriteLine("Second Method, Value = {0}", s);
    }
 //遍历字典
    foreach (KeyValuePair kvp in openWith)
    {
        Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
    }
//添加存在的元素
    try
    {
        openWith.Add("txt", "winword.exe");
    }
    catch (ArgumentException)
    {
        Console.WriteLine("An element with Key = \"txt\" already exists.");
    }
//删除元素
    openWith.Remove("doc");
    if (!openWith.ContainsKey("doc"))
    {
        Console.WriteLine("Key \"doc\" is not found.");
    }
//判断键存在
    if (openWith.ContainsKey("bmp")) // True 
    {
        Console.WriteLine("An element with Key = \"bmp\" exists.");
    }

参数为其他类型

//参数为其它类型 
    Dictionary OtherType = new Dictionary();
    OtherType.Add(1, "1,11,111".Split(','));
    OtherType.Add(2, "2,22,222".Split(','));
    Console.WriteLine(OtherType[1][2]);

参数为自定义类型

  class DouCube
    {
        public int Code{get { return _Code; } set { _Code = value; } } 
        private int _Code;
        public string Page { get { return _Page; } set { _Page = value; } } 
        private string _Page;
    } 
    //声明并添加元素
    Dictionary MyType = new Dictionary();
    for (int i = 1; i <= 9; i++)
    {
        DouCube element = new DouCube();
        element.Code = i * 100;
        element.Page = "http://www.doucube.com/" + i.ToString() + ".html";
        MyType.Add(i, element);
    }
    //遍历元素
    foreach (KeyValuePair kvp in MyType)
    {
        Console.WriteLine("Index {0} Code:{1} Page:{2}", kvp.Key, kvp.Value.Code, kvp.Value.Page);
    }

常用属性

名称 说明
Comparer 获取用于确定字典中的键是否相等的 IEqualityComparer
Count 获取包含在 Dictionary 中的键/值对的数目
Item 获取或设置与指定的键相关联的值。
Keys 获取包含 Dictionary 中的键的集合。
Values 获取包含 Dictionary 中的值的集合。

常用方法

名称 说明
Add 将指定的键和值添加到字典中。
Clear 从 Dictionary 中移除所有的键和值
ContainsKey 确定 Dictionary 是否包含指定的键
ContainsValue 确定 Dictionary 是否包含特定值
GetEnumerator 返回循环访问 Dictionary 的枚举器
GetObjectData 实现 System.Runtime.Serialization.ISerializable 接口,并返回序列化 Dictionary 实例所需的数据
GetType 获取当前实例的 Type。 (继承自 Object。)
MemberwiseClone 创建当前 Object 的浅表副本。 (继承自 Object。)
OnDeserialization 实现 System.Runtime.Serialization.ISerializable 接口,并在完成反序列化之后引发反序列化事件。
Remove 从 Dictionary 中移除所指定的键的值 TryGetValue 获取与指定的键相关联的值。
Equals(Object) 确定指定的 Object 是否等于当前的 Object。 (继承自 Object。
Finalize 允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。(继承自 Object。)
GetHashCode 用作特定类型的哈希函数。 (继承自 Object。)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

你可能感兴趣的:(C#字典Dictionary的用法说明(注重性能版))