在日常开发中。数据集合是我们不可缺少的重要工具之中的一个。在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. Mac上微信小程序官方开发工具卡死的问题

    Mac上微信小程序官方开发工具打开后卡死,无法操作,也关不掉,解决方案: 三步: 1.在应用中删除“微信web开发者工具” 2.删除一下几个配置和缓存文件: 1.-/Library/Applicati ...

  2. PHP学习1——快速入门

    主要内容: 搭建PHP开发环境 第一个helloworld程序 PHP(Hypertext Preprocessor)PHP超文本预处理程序,是一种嵌入HTML的脚本语言,运行在服务器. 搭建PHP开 ...

  3. MySQL---2、安装与部署

    1.MySQL下载 MySQL版本的选择MySQL Community Server 社区版本,开源免费,但不提供官方技术支持.MySQL Enterprise Edition 企业版本,需付费,可以 ...

  4. [转] 如何应用设计模式设计你的足球引擎(一和二)----Design Football Game(Part I and II)

    原文地址: http://www.codeproject.com/KB/architecture/applyingpatterns.aspx 作者:An 'OOP' Madhusudanan 译者:赖 ...

  5. 基于标注的AOP面向切面编程

    1.什么是AOP Aspect  Orientied   Programming的简称,即 面向(方面)切面编程 ,不改变一个组件源代码的情况下 可以对组件功能进行增强. 例如:servlet中的过滤 ...

  6. centos ssh远程登陆

    登录Centos6.5系统. ◆示例:使用root用户登录. 注:若为非root用户登录,输入执行某些命权限不够时需加sudo.   查看SSH是否安装. ◆输入命令:rpm -qa | grep s ...

  7. 用Jq遍历一个div里面的所有input 并判断是否为空?

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. git杂记-远程仓库的使用

    查看远程仓库:克隆自己的仓库,如不命名则默认远程仓库名字为origin: $ git clone https://github.com/OuFeng/JF_WEB.git Cloning into ' ...

  9. 【一些简单的jQuery选择器】

    学习[js DOM 编程艺术],最后面有许多jQuery的选择器,每个都动手敲了一遍. jQuery 提供了高级选择器的方法. js获取元素的三个基本方法分别是通过标签名,类名和id,即(getEle ...

  10. <Android 基础(二十一)> Android 屏幕适配

    基本概念 1. 什么是屏幕尺寸.屏幕分辨率.屏幕像素密度? 屏幕尺寸是指屏幕对角线的长度.单位是英寸,1英寸=2.54厘米 屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向 ...