首页 > 代码库 > [枫叶学院] Unity3d高级开发教程 工具集(一) 哈希列表——强大的自定义数据集
[枫叶学院] Unity3d高级开发教程 工具集(一) 哈希列表——强大的自定义数据集
在日常开发中,数据集合是我们必不可少的重要工具之一。在C#中,.Net Framework也为我们提供了种类繁多,功能多样的数据集工具。在此,我基于List<T> 和 HashTable制作了一个功能强大的数据集,我将其命名为HashList。他集二者的优势于一身,既支持数组索引的操作,同时也支持键值对操作。我更在此基础上封装了一些常用的工具函数,使其能够极大的方便我们日常开发中的数据管理。
HashList 核心功能如下:
1、类型安全的数据集合,省去了强制转换的繁冗操作
2、根据数组索引,哈希键值来添加,删除,读取数据
3、从序列的指定索引处截取指定长度
4、使用实现了ICompare接口的排序类进行排序
5、查找指定谓语条件的一组数据或单个数据
6、连接两个HashList数据集
不足之处:
1、原本打算使用双向链接表来替代List<T>,但是发现LinkedList无法实现数据集的过滤和排序,所以不得已又换回了了List<T>。如果哪位大神知道双向连接表的过滤和排序实现方法,还请不吝赐教。
2、由于C#是强类型语言,所以某些操作,特别是删除操作,对于HashList中的HashTable部分就显得比较困难,因为我无法去动态获取对象的key属性。(当然,反射可以做到,但是由于它的效率较低,所以我不打算使用)。目前实现的方法就是在HashTable中遍历比较,然后再删除。如果哪位大神有更好的方法,请不吝赐教。
另外,本代码中对于对象的打印使用的是Jayrock。
以下源码及Jayrock下载地址,请点这里。
废话少说,直接上源码:
HashList.cs
using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System; using UnityEngine; //************************************************************************************ //* 命名空间:xyxk; //* 版本号: V1.0.0.0; //* 创建人: 枫叶天空 (孙伟航); //* QQ : 1569423066; //* 电子邮箱:SunixSky@gmail.com //* 创建时间:2014-06-14; //* 描述 : 功能强大的自定义集合,同时兼容list与hashtable的核心功能; //************************************************************************************* namespace xyxk { /// <summary> /// 哈希列表; /// </summary> public class HashList<T> : IDisposable { //哈希表对象,用来进行键值数据处理; public Hashtable hash = new Hashtable(); //泛型列表,用来进行有序数据处理; public List<T> list = new List<T>(); //字符串格式化标志; //true 打印list; //false 打印hashTabel; public bool typeList = true; /////////////////////////////////////// public method //////////////////////////////////////////////////////////// /// <summary> /// 获取一个Array结构的数据集; /// </summary> /// <returns></returns> public T[] array { get { T[] array = new T[count]; list.CopyTo(array); return array; } } /// <summary> /// 从当前列表中指定的索引位置处截取num个对象,并返回; /// </summary> /// <param name="start">截取的起始索引</param> /// <param name="num">截取数量</param> /// <returns></returns> public List<T> splice(int start, int num) { T[] array = new T[num]; list.CopyTo(start,array,0,num); removeFromHashByArray(array); return array.ToList(); } /// <summary> /// 连接两个hashList; /// </summary> /// <param name="value"></param> public void concat(HashList<T> value) { list = list.Concat(value.list).ToList(); ; addFromHash(value.hash); } /// <summary> /// 通过键值添加对象; /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void addElement(object key, T value) { list.Add(value); hash.Add(key, value); } /// <summary> /// 向指定的索引处添加对象; /// </summary> /// <param name="value"></param> /// <param name="index"></param> public void addElement(object key, T value, int index) { list.Insert(index, value); hash.Add(key, value); } /// <summary> /// 获取指定索引处的对象; /// </summary> /// <param name="index"></param> /// <returns></returns> public T getElement(int index) { return list.ElementAtOrDefault(index); } /// <summary> /// 获取指定键值的对象; /// </summary> /// <param name="key"></param> /// <returns></returns> public T getElement(object key) { if (hash.ContainsKey(key)) return (T)hash[key]; return default(T); } /// <summary> /// 删除指定的对象; /// </summary> /// <param name="value"></param> public void removeElement(T value) { list.Remove(value); removeFromHash(value); } /// <summary> /// 删除指定键值的对象; /// </summary> /// <param name="key"></param> public void removeElement(object key) { T value = http://www.mamicode.com/(T)hash[key];>
同时附上测试代码,直接绑定在U3D的一个GameObject上即可。HashListTest.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using Jayrock.Json; namespace xyxk { public class HashListTest : MonoBehaviour { public HashList<CustomeData> hashList = new HashList<CustomeData>(); void Start() { testAddElement(); testConcat(); testSplice(); testValues(); testSort(); testIndexOf(hashList.getElement(3)); testFind(); testFindAll(); testShift(); testPop(); testGetElement(); testRemoveElement(); } /// <summary> /// 添加元素测试用例; /// </summary> public void testAddElement() { Debug.Log("====================testAddElement=========================="); for (int i = 0; i < 3; i++) { //直接添加对象引用; CustomeData data = new CustomeData(); data.key = "s" + i; data.name = "name" + i; data.level = i; data.Type = i % 2; hashList.addElement(data.key,data); } print("直接添加对象引用;-------result:" + hashList.ToString()); //将对象引用添加到指定的索引处; CustomeData data3 = new CustomeData(); data3.key = 3; data3.name = "name" + 3; data3.level = 3; data3.Type = -1; hashList.addElement(data3.key,data3, 0); print("将对象引用添加到指定的索引处;-------result:" + hashList.ToString()); //键值对方式添加; CustomeData data4 = new CustomeData(); data4.key = "4"; data4.name = "name" + 4; data4.level = 4; data4.Type = -1; hashList.addElement(data4.key, data4); print("键值对方式添加;-------result:" + hashList.ToString()); } /// <summary> /// 排序测试; /// </summary> public void testSort() { Debug.Log("====================testSort=========================="); hashList.sort(new SortLevel()); print("sort result:" + hashList.ToString()); } /// <summary> /// 获取元素测试用例; /// </summary> public void testGetElement() { Debug.Log("====================testGetElement=========================="); CustomeData data1 = hashList.getElement(0); print("通过索引获取对象; data1:" + data1.ToString()); CustomeData data2 = hashList.getElement("state2"); print("通过键值获取对象; data2:" + data2.ToString()); } /// <summary> /// 删除元素测试用例; /// </summary> public void testRemoveElement() { Debug.Log("====================testRemoveElement=========================="); //通过对象引用删除对象; CustomeData data = hashList.getElement(1); hashList.removeElement(data); print("通过对象引用删除对象;-------result:" + hashList.ToString()); //通过索引删除对象; hashList.removeElement(0); print("通过索引删除对象;-------result:" + hashList.ToString()); //通过键值删除对象; hashList.removeElement("s1"); print("通过键值删除对象;-------result:" + hashList.ToString()); } /// <summary> /// 获取列表中最后一个数据; /// </summary> public void testPop() { Debug.Log("====================testPop=========================="); CustomeData data = hashList.pop(); print("移除列表中的最后一个对象; data:" + data.ToString()); print("最终结果;-------result:" + hashList.ToString()); } /// <summary> /// 获取列表中第一个数据; /// </summary> public void testShift() { Debug.Log("====================testShift=========================="); CustomeData data = hashList.shift(); print("移除列表中的第一个对象; data:" + data.ToString()); print("最终结果;-------result:" + hashList.ToString()); } /// <summary> /// 查找指定谓语条件的单条数据; /// </summary> public void testFind() { Debug.Log("====================testFind=========================="); CustomeData data = hashList.find(CustomeData.findOne); print("查找结果;-------result:" + data.ToString()); } /// <summary> /// 查找指定谓语条件的数据集合; /// </summary> public void testFindAll() { Debug.Log("====================testFindAll=========================="); List<CustomeData> list = hashList.findAll(CustomeData.findByType); print("查找结果;-------result:" + Jayrock.Json.Conversion.JsonConvert.ExportToString(list)); } /// <summary> /// 查找给定元素的索引; /// </summary> /// <param name="data"></param> public void testIndexOf(CustomeData data) { Debug.Log("====================testIndexOf=========================="); int index = hashList.indexOf(data); print("索引值;------:" + index); } /// <summary> /// 数据的多种获取方式; /// </summary> public void testValues() { Debug.Log("====================testValues=========================="); List<CustomeData> list = hashList.list; Debug.Log("List 结构数据;-------:" + Jayrock.Json.Conversion.JsonConvert.ExportToString(list)); Hashtable hashTable = hashList.hash; Debug.Log("HashTable 结构数据;-------:" + Jayrock.Json.Conversion.JsonConvert.ExportToString(hashTable)); CustomeData[] array = hashList.array; Debug.Log("Array 结构数据;-------:" + Jayrock.Json.Conversion.JsonConvert.ExportToString(array)); } /// <summary> /// 连接两个hashList; /// </summary> public void testConcat() { Debug.Log("====================testConcat=========================="); HashList<CustomeData> list = new HashList<CustomeData>(); for (int i = 0; i < 3; i++) { //直接添加对象引用; CustomeData data = new CustomeData(); data.key = "state" + i; data.name = "nameK" + i; data.level = i; data.Type = i % 2; list.addElement(data.key, data); } Debug.Log("新表; ----" + list.ToString()); hashList.concat(list); Debug.Log("连接新表; ----" + hashList.ToString()); } /// <summary> /// 截取hashList; /// </summary> public void testSplice() { Debug.Log("====================testSplice=========================="); hashList.typeList = false; List<CustomeData> list = hashList.splice(3, 3); Debug.Log("截取数据; ----" + Jayrock.Json.Conversion.JsonConvert.ExportToString(list)); Debug.Log("剩余数据; ----" + hashList.ToString()); } } public class CustomeData { public string name; public int level; private int type = 0; public int Type { get { return type; } set { type = value; } } private object _key; public object key { get { return _key; } set { _key = value; } } public override string ToString() { return Jayrock.Json.Conversion.JsonConvert.ExportToString(this); } /// <summary> /// 查找等级为3,且type为-1的数据; /// </summary> /// <param name="data"></param> /// <returns></returns> public static bool findOne(CustomeData data) { return (data.level) == 3 && (data.type == -1); } /// <summary> /// 查找等级为3,且type为-1的数据; /// </summary> /// <param name="data"></param> /// <returns></returns> public static bool findByType(CustomeData data) { return data.type == -1; } } /// <summary> /// 根据数据的level字段进行倒序排列; /// </summary> public class SortLevel : IComparer<CustomeData> { public int Compare(CustomeData a, CustomeData b) { if (a.level <= b.level) return 1; else return -1; } } }
U3D开发交流QQ群 345305437 欢迎您的加入