首页 > 代码库 > [枫叶学院] 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     欢迎您的加入