Unity3D数据集合字典Dictionary和哈希表Hashtable学习
Posted 恬静的小魔龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D数据集合字典Dictionary和哈希表Hashtable学习相关的知识,希望对你有一定的参考价值。
推荐阅读
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
一、前言
在日常开发中,常常会用到数据集合,那么数据集合是什么呢,数据集合也没有想象中那么复杂。
数据集合就是专门用来存储数据、检索数据,以及对数据一系列操作的类。
这些类有:ArrayList数组、List列表、Queue队列、Dictionary字典、Hashtable哈希表、Stack堆栈。
在开发中,每种数据集合都有优缺点,今天就将这些数据集合进行归纳总结。
一是方便自己捋顺思路,二是可以帮助到对此理解不清晰的开发者。
这是本系列文章的第三篇:
【Unity3D数据集合】(一)数组集合Array学习
【Unity3D数据集合】(二)列表集合List及ListArray学习
【Unity3D数据集合】(三)字典Dictionary和哈希表Hashtable学习
【Unity3D数据集合】(四)堆栈Stack和队列Queue学习
【Unity3D数据集合】(五)链表LinkedList数据集合学习
【Unity3D数据集合】(六)散列集合HashSet和排序集合SortedSet学习
【Unity3D数据集合】(七)排序列表SortedList和排序字典SortedDictionary学习
【Unity3D数据集合】(八)点阵列BitArray学习
二、字典和哈希表集合介绍
1、字典Dictionary
字典是一种典型的键值对类型的数据结构,每一个元素都是由一个键值对(键key和值value)组成。
这种数据结构可以通过某个键来访问元素,所以字典也被称为映射或散列表。
字典的主要特性是根据键快速查找值,也可以自由添加和删除元素,这有点像List,但跟List不同的是,List是连续存储,直接定址的。 字典像链表,非连续存储,所以删除元素不需要移动后续元素,就没有在内存中移动后续元素的性能开销。
通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictionary 类是作为一个哈希表来实现的,Dictionary 没有顺序之分,这一点不同于list列表,有顺序之分。
键必须是唯一的,而值不需要唯一。
字典中的键和值都是object类型,所以可以是任何类型(比如:string、int、自定义类型等等)
2、哈希表Hashtable
哈希表Hashtable类实现了IDictionary接口,集合中的值也是以键值对(key/value)的形式存取的。
哈希表,也称为散列表,在该集合中每一个元素都是由键值对(key/value)的形式存放值。
需要注意的是,key是区分大小写的。
哈希表Hashtable中的键和值为object类型,所以哈希表Hashtable支持任何类型的键值对。
三、字典和哈希表的区别
说了这么多字典和哈希表,可以看出来两者非常的相似,这两个都是键值对的表现形式,那什么时候用字典什么时候用哈希表呢,下面就来看一下两者的区别:
1、多线程区别
单线程用字典,有泛型优势,读取速度快,容量利用更充分;
哈希表单线程写入,多线程读取
2、线程安全
字典非线程安全,必须人为的增加lock语句进行保护,影响效率。
哈希表可以调用Synchronized()方法可以获得完全线程安全的类型。
3、数据插入顺序
字典的排序就是按照插入的排序(注:删除节点后顺序就被打乱了),因此在需要体现顺序的情况下,字典更有效。
哈希表不是按照顺序插入数据的。
4、索引效率
字典在单线程索引数据的时候效率比较高,读取速度快,但是数据量大的时候效率会下降
哈希表的索引方式是经过散列处理的,在数据量大的时候处理效率更高,所以哈希表比较适合运用在做对象缓存,树递归算法的替代等各种需要提升效率的场合。
四、字典初始化
1、字典初始化
泛型集合,主要利用System.Collections.Generic命名空间下的Dictionary<TKey,TValue>创建集合:
Dictionary<TKey,TValue> table = new Dictionary<TKey,TValue>();
这个TKey/TValue,就是要使用的类型,可以是String、Int,比如下面的例子:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int,string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1,"张三");
table.Add(2,"李四");
foreach (KeyValuePair<int, string> item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
2、哈希表初始化
上面的例子已经演示了,如何初始化字典,如何添加数据,下面就看一下哈希表如何初始化:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1,"张三");//添加keyvalue键值对
table.Add(2,"李四");
//由于Hashtable每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型
//而是DictionaryEntry类型
foreach (DictionaryEntry item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
字典和哈希表使用方法基本一致。
哈希表与字典不同的是,哈希表不需要一开始就定义键值对的类型,甚至可以key的类型不一致,比如:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1, "张三");//添加keyvalue键值对
table.Add("王五", "李四");
table.Add(1.357f, 32);
//由于Hashtable每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型
//而是DictionaryEntry类型
foreach (DictionaryEntry item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
这样的好处是,不用在一开始就思考key和value的类型,因为哈希表是以散列表形式存放,所以更加灵活。
五、字典和哈希表的增删改查
1、查找数据
字典
通过key键寻找:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int, string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1, "张三");
table.Add(2, "李四");
Debug.Log(table[1]);
}
}
通过循环寻找:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int, string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1, "张三");
table.Add(2, "李四");
foreach (KeyValuePair<int, string> item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
哈希表
通过key值寻找:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();
table.Add(1, "张三");
table.Add("王五", "李四");
table.Add(1.357f, 32);
Debug.Log(table[1.357f]);
}
}
通过循环寻找:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1, "张三");//添加keyvalue键值对
table.Add("王五", "李四");
table.Add(1.357f, 32);
//由于Hashtable每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型
//而是DictionaryEntry类型
foreach (DictionaryEntry item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
2、修改数据
字典
可以直接通过key进行数据修改:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int, string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1, "张三");
table.Add(2, "李四");
table[1] = "王五";
Debug.Log(table[1]);
}
}
也可以在循环中,找到对应的数据进行修改:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int, string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1, "张三");
table.Add(2, "李四");
foreach (KeyValuePair<int, string> item in table)
{
if (item.Key > 0)
{
table[item.Key] = "修改名字";
}
Debug.Log(item.Key + " " + item.Value);
}
}
}
哈希表
通过key改:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1, "张三");
table.Add(2, "李四");
table.Add(3.45, "王五");
table[3.45] = "赵六";
}
}
循环改:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1, "张三");
table.Add(2, "李四");
//table.Add(3.45, "王五");
foreach (DictionaryEntry item in table)
{
if ((int)item.Key > 1)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
}
因为哈希表里面的键值都为object类型,所以进行数值计算的时候都要进行装箱拆箱运算。
如果类型不一致,还会导致装箱拆箱错误。
所以,一定要注意数值类型。
3、增加数据
字典
可以通过Add来增加数据:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int, string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1, "张三");
table.Add(2, "李四");
foreach (KeyValuePair<int, string> item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
table.Add(3, "王五");
foreach (KeyValuePair<int, string> item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
哈希表
可以通过Add来增加数据:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1, "张三");
table.Add(2, "李四");
foreach (DictionaryEntry item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
table.Add(3.45, "王五");//增加数据
foreach (DictionaryEntry item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
4、删除数据
字典
使用Remove删除指定key键的键值对数据元素:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Dictionary<int, string> table;
void Start()
{
table = new Dictionary<int, string>();
table.Add(1, "张三");
table.Add(2, "李四");
foreach (KeyValuePair<int, string> item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
table.Remove(1);
foreach (KeyValuePair<int, string> item in table)
{
Debug.Log(item.Key + " " + item.Value);
}
}
}
哈希表
使用Remove删除指定key键的键值对数据元素:
using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;
public class Demo5 : MonoBehaviour
{
Hashtable table;
void Start()
{
table = new Hashtable();//创建一个Hashtable实例
table.Add(1, "张三");
table.Add(2, "李四");
foreach (数据字典Dictionary存放键值对
python 数据类型: 数字Nubmer / 字符串String / 列表List / 元组Tuple / 集合Set / 字典Dictionary