对于上一章节介绍的委托和设计模式,更深一步的理解需要从项目中提升。
这章的主要内容是哈希表、字典、堆栈、队列的概念介绍,本节只介绍了构建和基本功能,后续在使用的过程中会继续添加内容进去。
一、哈希表
哈希表(Hash table,也叫散列表),是根据键(Key)而直接访问在内存存储位数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称为散列函数,存放记录的数组称做散列表。
哈希表其实本质上就是一个数组
一篇文章彻底搞懂哈希表
1:HashTable类代表了基于键的哈希代码组织起来的键/值 对集合。
它使用键来访问集合中的元素。
声明哈希表
public class hashTable : MonoBehaviour
{
Hashtable ht1=new Hashtable();
}
添加元素和常用功能
void Start()
{void Start()
{
ht1.Add("1",100); //类使用了object来写Key(键)和value,,此处添加了string类型1
ht1.Add(1,99); //此处添加了int 类型1
ht1.Clear(); //1:清空元素
if(ht1.ContainsKey("1")); //2:ContainsKey,查看是否包含功能
{
Debug.Log("ht1中包含key为"+"1"+"的数据");
}
ht1.Remove("1"); //3:移除字符串1
Debug.Log(ht1["1"]); //从哈希表中取出字符串类型的1
Debug.Log(ht1[1]); //从哈希表中取出Int类型的1
ht1[1]=999;//将原有元素1修改为999 //修改元素功能
ICollection key=ht1.Keys; //使用了Icollection指令,从哈希中取出所有的Key
foreach(var k in key)
{
Debug.Log(ht1[k]);
}
}
2:HashSet
包含不重复项的无序列表
Java基础(五):HashSet(使用方法详解)_Hi丶ImViper的博客-CSDN博客_hashset
①:HashSet的创建
HashSet<int> hs1 =new HashSet<int>();
HashSet<int> hs2 =new HashSet<int>();
private void Start()
{
hs1.Add(1);
hs1.Add(2);
hs1.Add(2);
Debug.Log(hs1.Count); //count是数量,如果有重复的,都视为一个
hs2.Add(2);
hs2.Add(3);
②并集操作
hs1.UnionWith(hs2); //UnionWith是并集的意思
foreach (var v in hs1) //经过并集后,hs1有了3
{
Debug.Log(v);
}
③交集操作
hs1.IntersectWith(hs2); //Intersectwith是交集的意思
foreach (var v in hs1) //,经过交集后,hs1只剩下2
{
Debug.Log(v);
}
④差集操作
hs1.ExceptWith(hs2); //ExceptWith是差集操作,在hs1里面看,如果hs2里面的元素,在
// hs1里面存在,则去除,如果没有,则不管
foreach (var v in hs1) //经过差集后,hs1成了1,
{
Debug.Log(v);
}
⑤对称差集操作
hs1.SymmetricExceptWith(hs2); //SymmertriciExceptWith是对称差集,表示去除两个集合中共有的元
// 素,只留下相互没有的元素
foreach (var v in hs1)
{
Debug.Log(v);
}
二、字典
字典:泛型容器,存储键值对数据的集合,它与HashTable的关系类似ArrayLise和List的关系
与哈希表的区别:字典定义时需要制定好类型,因此在使用的时候就没有装箱拆箱类型转换的步骤,执行效率较高
1:创建字典,添加元素
public class Dictonary : MonoBehaviour
{
Dictionary<string,string> dic1= new Dictionary<string,string>(); //创建dic1,并进行实例化
void Start()
{
dic1.Add("1","100"); //给dic1添加元素,键+值
dic1.Add("2","200");
dic1.Add("3","300");
}
2:常用功能
if (dic1.ContainsKey("1")) //1:判断是否包含
{
Debug.Log("键存在");
}
dic1["1"]="1000"; //2:修改第一个元素
foreach (KeyValuePair<string,string>kvp in dic1) //3:一种遍历方式
{
Debug.Log(kvp.Key+""+kvp.Value);
}
dic1.Remove("2"); //4:移除字符串2
dic1.Clear();
}
三、堆栈(stack)
Stack是先进后出的对象集合
1:堆栈
压栈指令Push, 出栈指令Pop , Peek指令是引用出栈最顶端的元素,但是并不出栈
public class 堆栈 : MonoBehaviour
{
Stack st1=new Stack();
void Start()
{
st1.Push("a"); //把a压在栈里面,a在最底端
st1.Push("b"); //把b压在a的上方,在出栈时,必须先从上方出来,所以是先进后出
st1.Push("c");
st1.Push("d");
Debug.Log(st1.Count); //count:计算堆栈的元素数量
string v= (string)st1.Pop(); //拉出来最上方元素,出栈
Debug.Log(v);
Debug.Log(st1.Count);
v= (string)st1.Peek(); //Peek是引用出栈最顶端的元素,但是并不出栈
Debug.Log(v);
Debug.Log(st1.Count);
foreach (var v1 in st1)//对剩下的三个元素进行遍历
{
Debug.Log(v1);
}
2:实现堆栈
public class 实现栈 : MonoBehaviour
{
class MyStack
{
class StackData
{
public StackData nextItem;
public object topData;
public StackData(StackData next , object data)
{
this.nextItem =next;
this.topData =data;
}
}
StackData top;
public void Push(object data)
{
top = new StackData(top,data);
}
public object pop()
{
object rs1 =top.topData;
top=top.nextItem;
return rs1;
}
}
private void Start()
{
MyStack ms =new MyStack();
ms.Push(1);
ms.Push(2);
ms.Push(3);
Debug.Log(ms.pop());
Debug.Log(ms.pop());
Debug.Log(ms.pop());
}
}
四、队列(queue)
queue是先进先出的容器
1:队列
创建有两种方法,分别是默认的object和泛型queue
进队的指令是Enqueue; 离队的操作是Dequeue
其他方法类似
public class 队列 : MonoBehaviour
{
Queue queue= new Queue(); //默认object类型的queue
Queue<int> queue2 = new Queue<int>(); //泛型queue,使用的更多
void Start()
{
queue.Enqueue("1"); //队列中进队列操作是enqueue
queue2.Enqueue(1);
queue2.Enqueue(2);
queue2.Enqueue(3);
int v =queue2.Dequeue(); //队列中离队是Dequeue
Debug.Log(v);
queue2.Enqueue(4);
//queue2.Clear/contain/count方法一样可用
foreach (var v1 in queue2)
{
Debug.Log(v1);
}
2:实现队列
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class 实现列 : MonoBehaviour
{
class MyQuene
{
class QueneData
{
public QueneData nextItem;
public object topData;
public QueneData(QueneData last, object data)
{
last.nextItem=this;
this.topData =data;
}
}
QueneData top;
QueneData lastData;
public void Enquene(object data)//进入队列
{
if(top==null)
{
top= new QueneData(data);
lastData=top;
}
else
{
lastData= new QueneData(lastData,data);
}
}
public object DeQuene() //出队列
{
object rs1 =top.topData;
top=top.nextItem;
return rs1;
}
}
private void Start()
{
MyQuene mq1=new MyQuene();
mq1.Enquene(1);
mq1.Enquene(2);
mq1.Enquene(3);
mq1.Enquene(4);
Debug.Log(mq1.DeQuene());
Debug.Log(mq1.DeQuene());
Debug.Log(mq1.DeQuene());
Debug.Log(mq1.DeQuene());
}
}