Unity基础之C#进阶篇笔记1:简单数据结构类
Arraylist
1.ArrayList的本质
//ArrayList是一个C#为我们封装好的类,
//它的本质是一个object类型的数组,
//ArrayList类帮助我们实现了很多方法,
//比如数组的增删查改
2.申明
//需要引用命名空间using System.Collections;
ArrayList array = new ArrayList();
3.增删查改
#region 增
array.Add(1);
array.Add("123");
array.Add(true);
array.Add(new object());
array.Add(new Test());
array.Add(1);
array.Add(true);
ArrayList array2 = new ArrayList();
array2.Add(123);
//范围增加(批量增加 把另一个list容器里面的内容加到后面)
array.AddRange(array2);
array.Insert(1, "12345676");
Console.WriteLine(array[1]);
#endregion
#region 删
//移除指定元素 从头找 找到删
array.Remove(1);
//移除指定位置的元素
array.RemoveAt(2);
//清空
//array.Clear();
#endregion
#region 查
//得到指定位置的元素
Console.WriteLine(array[0]);
//查看元素是否存在
if( array.Contains("1234") )
{
Console.WriteLine("存在123");
}
//正向查找元素位置
//找到的返回值 是位置 找不到 返回值 是-1
int index = array.IndexOf(true);
Console.WriteLine(index);
Console.WriteLine(array.IndexOf(false));
//反向查找元素位置
//返回时从头开始的索引数
index = array.LastIndexOf(true);
Console.WriteLine(index);
#endregion
#region 改
Console.WriteLine(array[0]);
array[0] = "999";
Console.WriteLine(array[0]);
#endregion
4.遍历
//长度
Console.WriteLine(array.Count);
//容量
//避免产生过多的垃圾
Console.WriteLine(array.Capacity);
Console.WriteLine("***********************");
for (int i = 0; i < array.Count; i++)
{
Console.WriteLine(array[i]);
}
Console.WriteLine("***********************");
//迭代器遍历
foreach (object item in array)
{
Console.WriteLine(item);
}
5.装箱拆箱
//ArrayList本质上是一个可以自动扩容的object数组,
//由于用万物之父来存储数据,自然存在装箱拆箱。
//当往其中进行值类型存储时就是在装箱,当将值类型对象取出来转换使用时,就存在拆箱。
//所以ArrayList尽量少用,之后我们会学习更好的数据容器。
int k = 1;
array[0] = k;//装箱
k = (int)array[0];//拆箱
6.练习题
1.练习题1
//请简述ArrayList和数组的区别
#region 答案
//ArrayList本质上是一个object数组的封装
//1.ArrayList可以不用一开始就定长,单独使用数组是定长的
//2.数组可以指定存储类型,ArrayList默认为object类型
//3.数组的增删需要我们自己去实现,ArrayList帮我们封装了方便的API来使用
//4.ArrayList使用时可能存在装箱拆箱,数组使用时只要不是object数组那就不存在这个问题
//5.数组长度为Length, ArrayList长度为Count
#endregion
2.练习题2
//创建一个背包管理类,使用ArrayList存储物品,
//实现购买物品,卖出物品,显示物品的功能。购买与卖出物品会导致金钱变化
class BagMgr
{
//背包中的物品
private ArrayList items;
private int money;
public BagMgr( int money )
{
this.money = money;
items = new ArrayList();
}
public void BuyItem(Item item)
{
if( item.num <= 0 || item.money < 0 )
{
Console.WriteLine("请传入正确的物品信息");
return;
}
if( this.money < item.money*item.num )
{
//买不起 钱不够
Console.WriteLine("买不起 钱不够");
return;
}
//减钱
this.money -= item.money * item.num;
Console.WriteLine("购买{0}{1}个花费{2}钱", item.name, item.num, item.money * item.num);
Console.WriteLine("剩余{0}元钱", this.money);
//如果想要叠加物品 可以在前面先判断 是否有这个物品 然后加数量
for (int i = 0; i < items.Count; i++)
{
if( (items[i] as Item).id == item.id )
{
//叠加数量
(items[i] as Item).num += item.num;
return;
}
}
//把一组物品加到 list中
items.Add(item);
}
public void SellItem(Item item)
{
for (int i = 0; i < items.Count; i++)
{
//如何判断 卖的东西我有没有
//这是在判断 两个引用地址 指向的是不是同一个房间
//所以我们要判断 卖的物品 一般不这样判断
//if(items[i] == item)
//{
//}
if( (items[i] as Item).id == item.id )
{
//两种情况
int num = 0;
string name = (items[i] as Item).name;
int money = (items[i] as Item).money;
if ((items[i] as Item).num > item.num)
{
//1.比我身上的少
num = item.num;
}
else
{
//2.大于等于我身上的东西数量
num = (items[i] as Item).num;
//卖完了 就从身上移除了
items.RemoveAt(i);
}
int sellMoney = (int)(num * money * 0.8f);
this.money += sellMoney;
Console.WriteLine("卖了{0}{1}个,赚了{2}钱", name, num, sellMoney);
Console.WriteLine("目前拥有{0}元钱", this.money);
return;
}
}
}
public void SellItem(int id, int num = 1)
{
//我这是想 直接调用上面写好的方法
//我就直接构造一个Item类 把ID和数量两个关键信息设置了即可 就可以卖了
Item item = new Item(id, num);
SellItem(item);
}
public void ShowItem()
{
Item item;
for (int i = 0; i < items.Count; i++)
{
item = items[i] as Item;
Console.WriteLine("有{0}{1}个", item.name, item.num);
}
Console.WriteLine("当前拥有{0}元钱", this.money);
}
}
class Item
{
//物品唯一ID 来区分物品的种类
public int id;
//物品多少钱(单价)
public int money;
//物品名字
public string name;
//public string tips;
//物品数量
public int num;
public Item(int id, int num)
{
this.id = id;
this.num = num;
}
public Item(int id, int money, string name, int num)
{
this.id = id;
this.money = money;
this.name = name;
this.num = num;
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("ArrayList练习题");
BagMgr bag = new BagMgr(99999);
Item i1 = new Item(1, 10, "红药", 10);
Item i2 = new Item(2, 20, "蓝药", 10);
Item i3 = new Item(3, 999, "屠龙刀", 1);
bag.BuyItem(i1);
bag.BuyItem(i2);
bag.BuyItem(i3);
bag.SellItem(i3);
bag.SellItem(1, 1);
bag.SellItem(1, 1);
bag.SellItem(2, 1);
bag.SellItem(2, 1);
}
}
Stack 栈
1.Stack的本质
//Stack(栈)是一个C#为我们封装好的类
//它的本质也是object[]数组,只是封装了特殊的存储规则
//Stack是栈存储容器,栈是一种先进后出的数据结构
//先存入的数据后获取,后存入的数据先获取
//栈是先进后出
2.申明
//需要引用命名空间 System.Collections
Stack stack = new Stack();
3.增取查改
#region 增
//压栈
stack.Push(1);
stack.Push("123");
stack.Push(true);
stack.Push(1.2f);
stack.Push(new Test());
#endregion
#region 取
//栈中不存在删除的概念
//只有取的概念
//弹栈
object v = stack.Pop();
Console.WriteLine(v);
v = stack.Pop();
Console.WriteLine(v);
#endregion
#region 查
//1.栈无法查看指定位置的 元素
// 只能查看栈顶的内容
v = stack.Peek();
Console.WriteLine(v);
v = stack.Peek();
Console.WriteLine(v);
//2.查看元素是否存在于栈中
if( stack.Contains("123") )
{
Console.WriteLine("存在123");
}
#endregion
#region 改
//栈无法改变其中的元素 只能压(存)和弹(取)
//实在要改 只有清空
stack.Clear();
Console.WriteLine(stack.Count);
stack.Push("1");
stack.Push(2);
stack.Push("哈哈哈");
#endregion
4.遍历
//1.长度
Console.WriteLine(stack.Count);
//2.用foreach遍历
// 而且遍历出来的顺序 也是从栈顶到栈底
foreach(object item in stack)
{
Console.WriteLine(item);
}
//3.还有一种遍历方式
// 将栈转换为object数组
// 遍历出来的顺序 也是从栈顶到栈底
object[] array = stack.ToArray();
for (int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);
}
Console.WriteLine(stack.Count);
//4.循环弹栈
while( stack.Count > 0 )
{
object o = stack.Pop();
Console.WriteLine(o);
}
Console.WriteLine(stack.Count);
5.装箱拆箱
//由于用万物之父来存储数据,自然存在装箱拆箱。
//当往其中进行值类型存储时就是在装箱
//当将值类型对象取出来转换使用时,就存在拆箱。
6.练习题
1.练习题1
//请简述栈的存储规则
//先进后出
2.练习题2
//写一个方法计算任意一个数的二进制数
//使用栈结构方式存储,之后打印出来
Calc(10);
Calc(2);
Calc(3);
Calc(8);
Calc(16);
static void Calc(uint num)
{
Console.Write("{0}的二进制是:", num);
Stack stack = new Stack();
while(true)
{
stack.Push(num % 2);
num /= 2;
if (num == 1)
{
stack.Push(num);
break;
}
}
//循环弹栈
while(stack.Count > 0)
{
Console.Write(stack.Pop());
}
Console.WriteLine();
}
Queue 队列
1.Queue 的本质
//Queue是一个C#为我们封装好的类
//它的本质也是object[]数组,只是封装了特殊的存储规则
//Queue是队列存储容器
//队列是一种先进先出的数据结构
//先存入的数据先获取,后存入的数据后获取
//先进先出
2.申明
//需要引用命名空间 System.Collections
Queue queue = new Queue();
3.增取查改
#region 增
queue.Enqueue(1);
queue.Enqueue("123");
queue.Enqueue(1.4f);
queue.Enqueue(new Test());
#endregion
#region 取
//队列中不存在删除的概念
//只有取的概念 取出先加入的对象
object v = queue.Dequeue();
Console.WriteLine(v);
v = queue.Dequeue();
Console.WriteLine(v);
#endregion
#region 查
//1.查看队列头部元素但不会移除
v = queue.Peek();
Console.WriteLine(v);
v = queue.Peek();
Console.WriteLine(v);
//2.查看元素是否存在于队列中
if( queue.Contains(1.4f) )
{
Console.WriteLine("队列中存在1.4f");
}
#endregion
#region 改
//队列无法改变其中的元素 只能进出队列
//实在要改 只有清
Console.WriteLine(queue.Count);
queue.Clear();
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
#endregion
4.遍历
//1.长度
Console.WriteLine(queue.Count);
//2.用foreach遍历
foreach (object item in queue)
{
Console.WriteLine(item);
}
//3.还有一种遍历方式
// 将队列转换为object数组
object[] array = queue.ToArray();
for (int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);
}
//4.循环出列
while(queue.Count>0)
{
object o = queue.Dequeue();
Console.WriteLine(o);
}
Console.WriteLine(queue.Count);
5.装箱拆箱
//由于用万物之父来存储数据,自然存在装箱拆箱。
//当往其中进行值类型存储时就是在装箱
//当将值类型对象取出来转换使用时,就存在拆箱。
6.练习题
1.练习题1
//请简述队列的存储规则
//先进先出
2.练习题2
//使用队列存储消息,一次性存10条消息,每隔一段时间打印一条消息
//控制台打印消息时要有明显停顿感
Queue queue = new Queue();
queue.Enqueue("获得10枚金币");
queue.Enqueue("获得屠龙刀x1");
queue.Enqueue("获得99枚金币");
queue.Enqueue("获得血瓶x1");
queue.Enqueue("获得85枚金币");
queue.Enqueue("获得11枚金币");
queue.Enqueue("获得2枚金币");
queue.Enqueue("获得91枚金币");
queue.Enqueue("获得73枚金币");
queue.Enqueue("获得645枚金币");
int updateIndex = 1;
while (true)
{
if( updateIndex % 99999999 == 0 )
{
if(queue.Count > 0)
{
Console.WriteLine(queue.Dequeue());
}
updateIndex = 0;
}
++updateIndex;
}
Hashtable 哈希表
1.Hashtalbe的本质
//Hashtable(又称散列表) 是基于键的哈希代码组织起来的 键/值对
//它的主要作用是提高数据查询的效率
//使用键来访问集合中的元素
2.声明
//需要引用命名空间 System.Collections
Hashtable hashtable = new Hashtable();
3.增删改查
#region 增
hashtable.Add(1, "123");
hashtable.Add("123", 2);
hashtable.Add(true, false);
hashtable.Add(false, false);
//注意:不能出现相同键
#endregion
#region 删
//1.只能通过键去删除
hashtable.Remove(1);
//2.删除不存在的键 没反应
hashtable.Remove(2);
//3.或者直接清空
hashtable.Clear();
hashtable.Add(1, "123");
hashtable.Add(2, "1234");
hashtable.Add(3, "123");
hashtable.Add("123123", 12);
#endregion
#region 查
//1.通过键查看值
// 找不到会返回空
Console.WriteLine(hashtable[1]);
Console.WriteLine(hashtable[4]);//null
Console.WriteLine(hashtable["123123"]);
//2.查看是否存在
//根据键检测
if( hashtable.Contains(2) )
{
Console.WriteLine("存在键为2的键值对");
}
if( hashtable.ContainsKey(2) )
{
Console.WriteLine("存在键为2的键值对");
}
//根据值检测
if( hashtable.ContainsValue(12) )
{
Console.WriteLine("存在值为12的键值对");
}
#endregion
#region 改
//只能改 键对应的值内容 无法修改键
Console.WriteLine(hashtable[1]);
hashtable[1] = 100.5f;
Console.WriteLine(hashtable[1]);
#endregion
4.遍历
//得到键值对 对数
Console.WriteLine(hashtable.Count);
//1.遍历所有键
foreach (object item in hashtable.Keys)
{
Console.WriteLine("键:"+item);
Console.WriteLine("值:"+hashtable[item]);
}
//2.遍历所有值
foreach (object item in hashtable.Values)
{
Console.WriteLine("值:" + item);
}
//3.键值对一起遍历
foreach (DictionaryEntry item in hashtable)
{
Console.WriteLine("键:" + item.Key + "值:" + item.Value);
}
//4.迭代器遍历法
IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator();
bool flag = myEnumerator.MoveNext();
while (flag)
{
Console.WriteLine("键:" + myEnumerator.Key + "值:" + myEnumerator.Value);
flag = myEnumerator.MoveNext();
}
5.装箱拆箱
//由于用万物之父来存储数据,自然存在装箱拆箱
//当往其中进行值类型存储时就是在装箱
//当将值类型对象取出来转换使用时,就存在拆箱
6.练习题
1.练习题1
//请描述Hashtable的存储规则
// 一个键值对形式存储的 容器
// 一个键 对应一个值
// 类型是object
2.练习题2
//制作一个怪物管理器,提供创建怪物
//移除怪物的方法。每个怪物都有自己的唯一ID
/// <summary>
/// 怪物管理器 因为一般 管理器 都是唯一的 所以把它做成 一个单例模式的对象
/// </summary>
class MonsterMgr
{
private static MonsterMgr instance = new MonsterMgr();
private Hashtable monstersTable = new Hashtable();
private MonsterMgr()
{
}
public static MonsterMgr Instance
{
get
{
return instance;
}
}
private int monsterID = 0;
public void AddMonster()
{
Monster monster = new Monster(monsterID);
Console.WriteLine("创建了id为{0}的怪物", monsterID);
++monsterID;
//Hashtable 的键 是不能重复的 所以一定是用唯一ID
monstersTable.Add(monster.id, monster);
}
public void RemoveMonster(int monsterID)
{
if( monstersTable.ContainsKey(monsterID) )
{
(monstersTable[monsterID] as Monster).Dead();
monstersTable.Remove(monsterID);
}
}
}
class Monster
{
public int id;
public Monster(int id)
{
this.id = id;
}
public void Dead()
{
Console.WriteLine("怪物{0}死亡", id);
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hashtable练习题");
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.AddMonster();
MonsterMgr.Instance.RemoveMonster(0);
MonsterMgr.Instance.RemoveMonster(3);
}
}