• [枫叶学院] 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 = (T)hash[key];
                list.Remove(value);
                hash.Remove(key);
            }
    
            /// <summary>
            /// 删除指定索引处的对象;
            /// </summary>
            /// <param name="index"></param>
            public void removeElement(int index)
            {
                T value = list.ElementAtOrDefault(index);
                list.Remove(value);
                removeFromHash(value);
            }
    
            /// <summary>
            /// 获取list中的最后一个对象,并将其从list中删除;
            /// </summary>
            /// <returns></returns>
            public T pop()
            {
                int index = list.Count - 1;
                T value = list.ElementAt(index);
                removeElement(index);
                return value;
            }
    
            /// <summary>
            /// 获取list中的第一个对象,并将其从list中删除;
            /// </summary>
            /// <returns></returns>
            public T shift()
            {
                T value = list.ElementAt(0);
                removeElement(0);
                return value;
            }
    
            /// <summary>
            /// 依据指定的接口排序类,对list进行排序,并将排序后的list返回;
            /// </summary>
            /// <param name="compare"></param>
            /// <returns></returns>
            public List<T> sort(IComparer<T> compare)
            {
                list.Sort(compare);
                return list;
            }
    
            /// <summary>
            /// 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List<T> 中的第一个匹配元素;
            /// </summary>
            /// <param name="match"></param>
            /// <returns></returns>
            public T find(Predicate<T> match)
            {
                return list.Find(match);
            }
    
            /// <summary>
            /// 检索与指定谓词定义的条件匹配的全部元素;
            /// </summary>
            /// <param name="match"></param>
            /// <returns></returns>
            public List<T> findAll(Predicate<T> match)
            {
                return list.FindAll(match);
            }
    
            /// <summary>
            /// 返回指定对象的索引;
            /// </summary>
            /// <param name="value"></param>
            /// <returns></returns>
            public int indexOf(T value) 
            {
                return list.IndexOf(value);
            }
    
            /// <summary>
            /// 清空列表中全部数据;
            /// </summary>
            public void clear()
            {
                list.Clear();
                hash.Clear();
            }
    
            /// <summary>
            /// 将列表转化成字符串;
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                if (typeList)
                    return Jayrock.Json.Conversion.JsonConvert.ExportToString(list);
                else
                    return Jayrock.Json.Conversion.JsonConvert.ExportToString(hash);
            }
    
            /// <summary>
            /// 获取list中包括的元素数;
            /// </summary>
            public int count
            {
                get
                {
                    return list.Count;
                }
            }
    
            /// <summary>
            /// 释放;
            /// </summary>
            public void Dispose()
            {
                Dispose(true);//释放全部的资源;
                GC.SuppressFinalize(this);//不须要再调用本对象的Finalize方法
            }
    ///////////////////////////////// protected method ///////////////////////////////////////////////////////
    
            /// <summary>
            /// 从hash表中删除指定对象;
            /// </summary>
            /// <param name="value"></param>
            protected void removeFromHash(T value)
            {
                object key = null;
                foreach (DictionaryEntry de in hash)
                {
                    if (de.Value.Equals(value))
                    {
                        key = de.Key;
                        break;
                    }
                }
                if (key != null)
                    hash.Remove(key);
            }
    
            /// <summary>
            /// 从指定的数组中删除对象;
            /// </summary>
            /// <param name="array"></param>
            protected void removeFromHashByArray(T[] array)
            {
                int length = array.Length;
                for (int i = 0; i < length; i++ )
                    removeElement(array[i]);
            }
    
            /// <summary>
            /// 释放对象;
            /// </summary>
            /// <param name="disposing">是否清理托管资源</param>
            protected virtual void Dispose(bool disposing)
            {
                clear();
                //清理托管资源;
                if (disposing)
                {
                    list = null;
                    hash = null;
                }
            }
    
            /// <summary>
            /// 从指定的hash表中加入数据;
            /// </summary>
            /// <param name="value"></param>
            protected void addFromHash(Hashtable value)
            {
                foreach (DictionaryEntry de in value)
                {
                    hash.Add(de.Key, de.Value);
                }
            }
        }
    }
     
    

    同一时候附上測试代码,直接绑定在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     欢迎您的加入

  • 相关阅读:
    技术债务MartinFlower
    如何定义产品愿景
    领域驱动设计阶段知识总结
    领域驱动设计的价值
    什么是数字产品
    NestOS 发布:基于华为欧拉开源系统的云底座操作系统
    架子鼓MIDI及相关软件
    TM4 JDK1.8连接SqlServer报错:The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL)
    关于GPL协议的理解(开源与商用、免费与收费的理解)
    nest js 限制客户端在一定时间内的请求次数
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10684850.html
Copyright © 2020-2023  润新知