在日常开发中。数据集合是我们不可缺少的重要工具之中的一个。在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     欢迎您的加入

[枫叶学院] Unity3d高级开发教程 工具集(一) 哈希列表——强大的自己定义数据集的更多相关文章

  1. Android SDK:Android standard develop kits 安卓开发的工具集

    目前主流的安卓开发工具: 1.Adnroid-Adt-bundle SDK Manager.exe: Tools(安卓的开发小工具) 各种安卓版本 Extras 额外的开发包 在线更新/安装的安卓版本 ...

  2. ASP.NET Aries 高级开发教程:Excel导入之代码编写(番外篇)

    前言: 以许框架提供的导入配置功能,已经能解决95%以上的导入情况,但有些情况总归还是得代码来解决. 本篇介绍与导入相关的代码. 1.前端追加导入时Post的参数: var grid = new AR ...

  3. ASP.NET Aries 高级开发教程:Excel导入之单表配置(上)

    前言: 随着ASP.NET Aries的普及,刚好也有点闲空,赶紧把Excel导入功能的教程补上. Excel导入功能,分为四篇:单表配置(上).多表高级配置(中).配置规则(下).代码编写(番外篇) ...

  4. Android应用开发高效工具集1---ant构建简单Android项目

    本文转载于:http://blog.csdn.net/lincyang/article/details/40950153 在java编译那些事儿中提到了用ant去编译Java项目,今天扩展到用它来构建 ...

  5. ASP.NET Aries 高级开发教程:主题样式及多语言(标签化控制)

    前言: 最新ASP.NET Aries升级到V5.2.0以上之后,之前的样式和多语言机制,有了重大的升级机制,这篇就简单介绍一下. 1.控制开关 在配置维护那里,新增了两个控制项: 2.如何添加主题 ...

  6. ASP.NET Aries 高级开发教程:Excel导入之多表高级导入配置(中)

    前言: 在面对Excel的各种复杂导入情况中,多表导入是很常见的情景. 今天就来写一下多表导入是如何配置的. 1.自定义导入模板 怎么自定义: 其实就是自己新建一个Excel了,把列头都写好. 不过有 ...

  7. ASP.NET Aries 高级开发教程:如何写WebAPI接口

    前提: 最近,有不少同学又问到,Aries里如何提供WebAPI接口? 针对这个问题,今天给顺路写个教程,其实呢,很简单的. 方式一:直接用WebService提供接口. 用这种方式,直接添加接口就可 ...

  8. ASP.NET Aries 高级开发教程:使用存储过程(番外篇)

    前言: 发现这个问题,有不少人提起过,所以就简单写成文章吧. 接下来看如何在Aries 框架中使用存储过程,整体步骤和绑定普通视图差不多. 步骤一:新建一个空视图. 可以在SqlCode管理中,创建一 ...

  9. ASP.NET Aries 高级开发教程:Excel导入配置之规则说明(下)

    前言: 前面两篇都是大体介绍流程,有一些配置细节,没有细说,这里用一篇补上. 1.Excel配置项 起始行索引.列头跨行数: 对于自定义的Excel导入模板(有时候模板是由客户提供,模板的规则很乱) ...

随机推荐

  1. MySQL---1、介绍

    一.MySQL简介 1.MySQL简介 MySQL是一个轻量级关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.目前MySQL被广泛地应用在Internet上的中小型网站 ...

  2. mysql8.0遇到删除外键的错误

    错误信息:Cannot drop index 'energy_type_id': needed in a foreign key constraint 创建device表的信息 CREATE TABL ...

  3. 五:SpringCloud-Zuul

    九:zuul路由网关 1.概述 1.1 是什么 Zuul包含了对请求的路由和过滤两个最主要的功能: 其中==路由功能==负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础. 而==过 ...

  4. 三、hdfs的JavaAPI操作

    下文展示Java的API如何操作hdfs,在这之前你需要先安装配置好hdfs https://www.cnblogs.com/lay2017/p/9919905.html 依赖 你需要引入依赖如下 & ...

  5. spring data jpa(一)

    第1章     Spring Data JPA的快速入门 1.1   需求说明 Spring Data JPA完成客户的基本CRUD操作 1.2   搭建Spring Data JPA的开发环境 1. ...

  6. hdu 1075 What Are You Talking About 字典树模板

    What Are You Talking About Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/204800 K ...

  7. UOJ#414. 【APIO2018】新家

    传送门 首先二分答案 \(mid\),问题变成求区间 \([l-mid,r+mid]\) 在该年份的不同类型个数为 \(k\) 关于年份的限制可以离线下来 现在的问题就是区间数颜色,一个套路就是维护每 ...

  8. 03.CSS动画-->自定义动画

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. border-radius圆角兼容方案

    1.下载ie-css3.htc 2.CSS代码段 box { -moz-border-radius: 15px; /* Firefox */ -webkit-border-radius: 15px; ...

  10. centos7上安装python3

    一.安装环境及版本 CentOS 6.5 Python 3.6.1 二.安装依赖包 1.安装静态库 # yum install -y openssl-static 注:如果不安装该静态库,会导致pyt ...