C#学习记录--更新中

C#学习记录--更新中

  • C#进阶
    • ArrayList
      • 增删查改
      • 装箱拆箱
      • 练习
      • ArrayList和数组的区别
      • ArrayList和List的区别
    • Stack
      • Stack的本质
      • 增取查改
      • 遍历
      • 装箱拆箱
      • 栈的存储规则
      • 练习
    • Queue
      • 增取查改
      • 装箱拆箱
      • 队列的存储规则
      • 练习
    • Hashtable散列表
      • Hashtable的本质
      • 增删查改
      • 遍历
      • 装箱拆箱
      • Hashtable的存储规则
      • 练习
    • 泛型
      • 泛型是什么
      • 泛型分类
      • 泛型方法
      • 泛型的作用
      • 练习题
    • 泛型约束
      • 什么是泛型约束
      • 各泛型约束讲解
        • 值类型约束
        • 引用类型约束
        • 存在无参公共构造函数
        • 类约束
        • 接口约束
        • 另一个泛型约束
      • 约束的组合使用
      • 多个泛型有约束
      • 练习
    • List
      • 增删查改
      • 遍历
      • List和ArrayList的区别
      • 练习
    • Dictionary
      • Dictionary的本质
      • 增删查改
      • 遍历
      • 练习
    • 顺序存储和链式存储
      • 数据结构
      • 线性表
      • 顺序存储
      • 链式存储
      • 自己实现一个最简单的单向链表
      • 顺序存储和链式存储的优缺点
      • 常用的数据结构有哪些
      • 顺序存储和链式存储的区别
      • 练习
    • LinkedList
      • 增删查改
      • 遍历
      • 练习
    • 数据容器
      • 变量
      • 复杂数据容器
      • 数据集合
      • 泛型数据集合
    • 泛型栈和队列
    • 如何使用数据容器

C#进阶

ArrayList

ArrayList是一个C#为我们封装好的类,
它的本质是一个object类型的数组,
ArrayList类帮助我们实现了很多方法,
比如数组的增删查改

//需要引用命名空间using System.Collections;
ArrayList array = new ArrayList();

增删查改

 array.Add(1);array.Add(new Test());array.Add("123");
//加一个ArrayList
ArrayList array2 = new ArrayList();
array2.AddRange(array2);

// 移除指定元素,从头找
array.RemoveAt(1);
//指定位置
array.RemoveAt(2);
array.Clear();

//得到指定位置的元素
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);
#endregionif (array.Contains("123"))
{Console.WriteLine("存在123");
}

 Console.WriteLine(array[0]);array[0] = "999";Console.WriteLine(array[0]);array.Insert(1, "1236547");

遍历

//长度
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);
}

装箱拆箱

装箱就是把栈上的内存转移到堆上面,拆箱就是把堆上面的内存转移到栈上面

ArrayList本质上是一个可以自动扩容的object数组

当往其中进行值类型存储时就是在装箱,当将值类型对象取出来转换使用时,就存在拆箱

 int k = 1;array[0] = k;//装箱k = (int)array[0];//拆箱

练习

创建一个背包管理类,使用ArrayList存储物品,
实现购买物品,卖出物品,显示物品的功能。购买与卖出物品会导致金钱变化

ArrayList和数组的区别

  1. ArrayList可以不用一开始就是定长的,而数组是定长的
  2. ArrayList默认是object类型,而数组可以指定存储类型
  3. ArrayList封装了很多增删查改API,而数组需要自己实现
  4. ArrayList使用时候存在装箱拆箱,而数组只要使用时候不是object数组就不存在这个问题
  5. 数组长度为Length,ArrayList长度为Count,容量为Capecity

ArrayList和List的区别

  1. ArrayList 不带泛型 数据类型丢失,而List 带泛型 数据类型不丢失
  2. ArrayList 需要装箱拆箱 List不需要
  3. 在声明List集合时,我们同时需要为其声明List集合内数据的对象类型(带泛型)
ArrayList存在不安全类型(ArrayList会把所有插 ⼊其中的数据都当做Object来处理)装箱拆箱的 操作(费时)IList是接⼝,ArrayList是⼀个实现了 该接⼝的类,可以被实例化
List类是ArrayList类的泛型等效类。它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。

Stack

Stack的本质

它的本质也是object[]数组,只是封装了特殊的存储规则

栈是先进后出

Stack(栈)是一个C#为我们封装好的类Stack是栈存储容器,栈是一种先进后出的数据结构
先存入的数据后获取,后存入的数据先获取
//需要引用命名空间 System.Collections
Stack stack = new Stack();

增取查改

//压栈
stack.Push(231);
stack.Push(1);
stack.Push("123");
stack.Push(true);
stack.Push(1.2f);
stack.Push(new Test());

//栈中不存在删除的概念
//只有取的概念
//弹栈
object v = stack.Pop();Console.WriteLine(v);v = stack.Pop();
Console.WriteLine(v);

//1.栈无法查看指定位置的 元素
//  只能查看栈顶的内容
v = stack.Peek();
Console.WriteLine(v);
v = stack.Peek();
Console.WriteLine(v);//2.查看元素是否存在于栈中
if( stack.Contains("123") )
{Console.WriteLine("存在123");
}

//栈无法改变其中的元素 只能压(存)和弹(取)
//实在要改 只有清空
stack.Clear();
Console.WriteLine(stack.Count);
stack.Push("1");
stack.Push(2);
stack.Push("哈哈哈");

遍历

//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);

装箱拆箱

由于用万物之父来存储数据,自然存在装箱拆箱。
当往其中进行值类型存储时就是在装箱
当将值类型对象取出来转换使用时,就存在拆箱。

栈的存储规则

先进后出

练习

写一个方法计算任意一个数的二进制数
使用栈结构方式存储,之后打印出来

Queue

它的本质也是object[]数组,只是封装了特殊的存储规则

先进先出

Queue是一个C#为我们封装好的类Queue是队列存储容器
队列是一种先进先出的数据结构
先存入的数据先获取,后存入的数据后获取
//需要引用命名空间 System.Collections
Queue queue = new Queue();

增取查改

queue.Enqueue(1);
queue.Enqueue("123");
queue.Enqueue(1.4f);
queue.Enqueue(new Test());queue.Enqueue("!23");

//队列中不存在删除的概念
//只有取的概念 取出先加入的对象
object v = queue.Dequeue();
Console.WriteLine(v);
v = queue.Dequeue();
Console.WriteLine(v);

//1.查看队列头部元素但不会移除
v = queue.Peek();
Console.WriteLine(v);
v = queue.Peek();
Console.WriteLine(v);v = quque.Peek();//2.查看元素是否存在于队列中
if( queue.Contains(1.4f) )
{Console.WriteLine("队列中存在1.4f");
}

//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);

装箱拆箱

由于用万物之父来存储数据,自然存在装箱拆箱。
当往其中进行值类型存储时就是在装箱
当将值类型对象取出来转换使用时,就存在拆箱。

队列的存储规则

先进先出

练习

使用队列存储消息,一次性存10条消息,每隔一段时间打印一条消息
控制台打印消息时要有明显停顿感

Hashtable散列表

Hashtable的本质

Hashtable(又称散列表) 是基于键的哈希代码组织起来的 键/ 值对
它的主要作用是提高数据查询的效率
使用键来访问集合中的元素
//需要引用命名空间 System.Collections
Hashtable hashtable = new Hashtable();

增删查改

 hashtable.Add(1, "123");hashtable.Add("123", 2);hashtable.Add(true, false);hashtable.Add(false, false);//注意:不能出现相同键

 //1.只能通过键去删除hashtable.Remove(1);//2.删除不存在的键 没反应hashtable.Remove(2);//3.或者直接清空hashtable.Clear();

//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的键值对");
}

//只能改 键对应的值内容 无法修改键
Console.WriteLine(hashtable[1]);
hashtable[1] = 100.5f;
Console.WriteLine(hashtable[1]);

遍历

//得到键值对 数量
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();
}

装箱拆箱

由于用万物之父来存储数据,自然存在装箱拆箱
当往其中进行值类型存储时就是在装箱
当将值类型对象取出来转换使用时,就存在拆箱

Hashtable的存储规则

一个键值对形式存储的 容器
一个键 对应一个值
类型是object

练习

制作一个怪物管理器,提供创建怪物
移除怪物的方法。每个怪物都有自己的唯一ID

泛型

泛型是什么

泛型实现了类型参数化,达到代码重用目的
通过类型参数化来实现同一份代码上操作多种类型

泛型相当于类型占位符

定义类或方法时使用替代符代表变量类型

当真正使用类或者方法时再具体指定类型

泛型分类

泛型类和泛型接口

基本语法:
class 类名<泛型占位字母>
interface 接口名<泛型占位字母>

class A<T>
{public T Value;
}interface B<T>
{T Value{get;set;}
}

泛型函数
基本语法:函数名<泛型占位字母>(参数列表)
注意:泛型占位字母可以有多个,用逗号分开

泛型方法

  1. 普通类中的泛型方法
class Test2
{public void TestFun<T>( T value){Console.WriteLine(value);}public void TestFun<T>(){//用泛型类型 在里面做一些逻辑处理,default不管T是什么类型都会得到默认值T t = default(T);}public T TestFun<T>(string v){return default(T);}public void TestFun<T,K,M>(T t, K k, M m){}
}
  1. 泛型类中的泛型方法
//虽然和前面的类名一样,但是是不同的类,因为这里泛型属于类的一部分 
class Test2<T>{public T value;public void TestFun<K>(K k){Console.WriteLine(k);}//这个不叫泛型方法 因为 T是泛型类申明的时候 就指定 在使用这个函数的时候 //我们不能再去动态的变化了public void TestFun(T t){}}

泛型的作用

  1. 不同类型对象的相同逻辑处理就可以选择泛型

  2. 使用泛型可以一定程度避免装箱拆箱
    举例:优化ArrayList

class ArrayList<T>
{private T[] array;public void Add(T value){}public void Remove( T value){}
}
1.申明泛型时 它只是一个类型的占位符
2.泛型真正起作用的时候 是在使用它的时候
3.泛型占位字母可以有n个用逗号分开
4.泛型占位字母一般是大写字母
5.不确定泛型类型时 获取默认值 可以使用default(占位字符)
6.看到<> 包裹的字母 那肯定是泛型

练习题

定义一个泛型方法,方法内判断该类型为何类型,并返回类型的名称与占有的字节数
如果是int,则返回“整形,4字节”
只考虑以下类型
int:整形
char:字符
float:单精度浮点数
string:字符串
如果是其它类型,则返回“其它类型”
(可以通过typeof(类型) == typeof(类型)的方式进行类型判断)

泛型约束

什么是泛型约束

让泛型的类型有一定的限制
关键字:where
泛型约束一共有6种
1.值类型 where 泛型字母:struct
2.引用类型 where 泛型字母:class
3.存在无参公共构造函数 where 泛型字母:new ()
4.某个类本身或者其派生类 where 泛型字母:类名
5.某个接口的派生类型 where 泛型字母:接口名
6.另一个泛型类型本身或者派生类型 where 泛型字母:另一个泛型字母where 泛型字母:(约束的类型)

各泛型约束讲解

值类型约束
class Test1<T> where T:struct
{public T value;public void TestFun<K>(K v) where K:struct{}
}
引用类型约束
class Test2<T> where T:class
{public T value;public void TestFun<K>(K k) where K:class{}
}
存在无参公共构造函数
class Test3<T> where T:new()
{public T value;public void TestFun<K>(K k) where K : new(){}
}
class Test1
{public Test1(){}
}class Test2
{public Test2(int a){}
}Test3<Test1> a = new Test3<Test1>();
类约束
 class Test4<T> where T : Test1{public T value;public void TestFun<K>(K k) where K : Test1{}}class Test3:Test1{}
接口约束
interface IFly
{}interface IMove:IFly
{}class Test4:IFly
{}class Test5<T> where T : IFly
{public T value;public void TestFun<K>(K k) where K : IFly{}
}
另一个泛型约束
class Test6<T, U> where T : U
{public T value;public void TestFun<K,V>(K k) where K : V{}
}Test6<Test4, IFly> t6 = new Test6<Test4, IFly>();

约束的组合使用

 class Test7<T> where T: class,new(){}

多个泛型有约束

 class Test8<T,K> where T:class,new() where K:struct{}
泛型约束:让类型有一定限制
class
struct
new ()
类名
接口名
另一个泛型字母注意:
1.可以组合使用
2.多个泛型约束 用where连接即可

练习

  1. 用泛型实现一个单例模式基类
  2. 利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类
    实现增删查改方法

List

List是一个C#为我们封装好的类,
它的本质是一个可变类型的泛型数组
List类帮助我们实现了很多方法,
比如泛型数组的增删查改

//需要引用命名空间
//using System.Collections.Generic
List<int> list = new List<int>();
List<string> list2 = new List<string>();
List<bool> list3 = new List<bool>();
List<string> list5 = new List<string>();

增删查改

list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);list2.Add("123");List<string> listStr = new List<string>();
listStr.Add("123");
list2.AddRange(listStr);list.Insert(0, 999);
Console.WriteLine(list[0]);

//1.移除指定元素
list.Remove(1);
//2.移除指定位置的元素
list.RemoveAt(0);
//3.清空
list.Clear();

//1.得到指定位置的元素
Console.WriteLine(list[0]);
//2.查看元素是否存在
if( list.Contains(1) )
{Console.WriteLine("存在元素 1");
}
//3.正向查找元素位置
// 找到返回位置 找不到 返回-1
int index = list.IndexOf(5);
Console.WriteLine(index);
//4.反向查找元素位置
// 找到返回位置 找不到 返回-1
index = list.LastIndexOf(2);
Console.WriteLine(index);

Console.WriteLine(list[0]);
list[0] = 99;
Console.WriteLine(list[0]);

遍历

//长度
Console.WriteLine(list.Count);
//容量
//避免产生垃圾
Console.WriteLine(list.Capacity);
Console.WriteLine("**********************");
for (int i = 0; i < list.Count; i++)
{Console.WriteLine(list[i]);
}
Console.WriteLine("**********************");
foreach (int item in list)
{Console.WriteLine(item);
}

List和ArrayList的区别

List内部封装的是一个泛型数组
ArrayList内部封装的是一个object数组

练习

  1. 建立一个整形List,为它添加10~1
    删除List中第五个元素
    遍历剩余元素并打印

  2. 一个Monster基类,Boss和Gablin类继承它。
    在怪物类的构造函数中,将其存储到一个怪物List中
    遍历列表可以让Boss和Gablin对象产生不同攻击

Dictionary

Dictionary的本质

可以将Dictionary理解为 拥有泛型的Hashtable
它也是基于键的哈希代码组织起来的 键/ 值对
键值对类型从Hashtable的object变为了可以自己制定的泛型
//需要引用命名空间 using System.Collections.Generic
Dictionary<int, string> dictionary = new Dictionary<int, string>();

增删查改

//注意:不能出现相同键
dictionary.Add(1, "123");
dictionary.Add(2, "222");
dictionary.Add(3, "222");dictionary.Add(4, "sss");

//1.只能通过键去删除
//  删除不存在键 没反应
dictionary.Remove(1);
dictionary.Remove(4);//2.清空
dictionary.Clear();
dictionary.Add(1, "123");
dictionary.Add(2, "222");
dictionary.Add(3, "222");

//1.通过键查看值
//  找不到直接报错
Console.WriteLine(dictionary[2]);
//Console.WriteLine(dictionary[4]);
Console.WriteLine(dictionary[1]);//2.查看是否存在
//  根据键检测
if( dictionary.ContainsKey(4) )
{Console.WriteLine("存在键为1的键值对");
}
//  根据值检测
if (dictionary.ContainsValue("1234"))
{Console.WriteLine("存在值为123的键值对");
}

 Console.WriteLine(dictionary[1]);dictionary[1] = "555";Console.WriteLine(dictionary[1]);

遍历

Console.WriteLine("**************");
Console.WriteLine(dictionary.Count);
//1.遍历所有键
foreach (int item in dictionary.Keys)
{Console.WriteLine(item);Console.WriteLine(dictionary[item]);
}
//2.遍历所有值
Console.WriteLine("**************");
foreach (string item in dictionary.Values)
{Console.WriteLine(item);
}
//3.键值对一起遍历
Console.WriteLine("**************");
foreach (KeyValuePair<int,string> item in dictionary)
{Console.WriteLine("键:" + item.Key + "值:" + item.Value);
}

练习

  1. 使用字典存储0~9的数字对应的大写文字
    提示用户输入一个不超过三位的数,提供一个方法,返回数的大写
    例如:306,返回叁零陆
    
  2. 计算每个字母出现的次数“Welcome to Unity World!”,使用字典存储,最后遍历整个字典,不区分大小写

Dictionary<char, int> dic = new Dictionary<char, int>();
string str = "Welcome to Unity World!";
str = str.ToLower();
for (int i = 0; i < str.Length; i++)
{if( dic.ContainsKey(str[i]) ){dic[str[i]] += 1;}else{dic.Add(str[i], 1);}
}foreach (char item in dic.Keys)
{Console.WriteLine("字母{0}出现了{1}次", item, dic[item]);
}

顺序存储和链式存储

数据结构

数据结构是计算机存储、组织数据的方式(规则)
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合
比如自定义的一个 类 也可以称为一种数据结构 自己定义的数据组合规则不要把数据结构想的太复杂
简单点理解,就是人定义的 存储数据 和 表示数据之间关系 的规则而已常用的数据结构(前辈总结和制定的一些经典规则)
数组、栈、队列、链表、树、图、堆、散列表

线性表

线性表是一种数据结构,是由n个具有相同特性的数据元素有限序列
比如数组、ArrayList、Stack、Queue、链表等等

顺序存储和链式存储 是数据结构中两种 存储结构

顺序存储

数组、Stack、Queue、List、ArrayList —— 顺序存储
只是 数组、Stack、Queue的组织规则不同而已

顺序存储:
一组地址连续的存储单元依次存储线性表的各个数据元素

链式存储

单向链表、双向链表、循环链表 —— 链式存储
链式存储(链接存储):
用一组任意的存储单元存储线性表中的各个数据元素

自己实现一个最简单的单向链表

/// <summary>
/// 单向链表节点
/// </summary>
/// <typeparam name="T"></typeparam>
class LinkedNode<T>
{public T value;//这个存储下一个元素是谁 相当于钩子public LinkedNode<T> nextNode;public LinkedNode(T value){this.value = value;}
}/// <summary>
/// 单向链表类 管理 节点 管理 添加等等
/// </summary>
/// <typeparam name="T"></typeparam>
class LindedList<T>
{public LinkedNode<T> head;public LinkedNode<T> last;public void Add(T value){//添加节点 必然是new一个新的节点LinkedNode<T> node = new LinkedNode<T>(value);if( head == null ){head = node;last = node;}else{last.nextNode = node;last = node;}}public void Remove(T value){if( head == null ){return;}if( head.value.Equals(value) ){head = head.nextNode;//如果头节点 被移除 发现头节点变空//证明只有一个节点 那尾也要清空if( head == null ){last = null;}return;}LinkedNode<T> node = head;while(node.nextNode != null){if( node.nextNode.value.Equals(value) ){//让当前找到的这个元素的 上一个节点//指向 自己的下一个节点node.nextNode = node.nextNode.nextNode;break;}}}
}

顺序存储和链式存储的优缺点

从增删查改的角度去思考
增:链式存储 计算上 优于顺序存储 (中间插入时链式不用像顺序一样去移动位置)
删:链式存储 计算上 优于顺序存储 (中间删除时链式不用像顺序一样去移动位置)
查:顺序存储 使用上 优于链式存储 (数组可以直接通过下标得到元素,链式需要遍历)
改:顺序存储 使用上 优于链式存储 (数组可以直接通过下标得到元素,链式需要遍历)

常用的数据结构有哪些

数组、栈、队列、链表、树、图、堆、散列表

顺序存储和链式存储的区别

顺序存储:内存中用一组地址连续的存储单元存储线性表(连续地址存储)
链式存储:内存中用一组任意的存储单元存储线性表(任意地址存储)

练习

请尝试自己实现一个双向链表
并提供以下方法和属性
数据的个数,头节点,尾节点
增加数据到链表最后
删除指定位置节点

LinkedList

LinkedList是一个C#为我们封装好的类
它的本质是一个可变类型的泛型双向链表

 //需要引用命名空间//using System.Collections.GenericLinkedList<int> linkedList = new LinkedList<int>();LinkedList<string> linkedList2 = new LinkedList<string>();//链表对象 需要掌握两个类//一个是链表本身 一个是链表节点类LinkedListNode

增删查改

 //1.在链表尾部添加元素linkedList.AddLast(10);//2.在链表头部添加元素linkedList.AddFirst(20);//3.在某一个节点之后添加一个节点//  要指定节点 先得得到一个节点LinkedListNode<int> n = linkedList.Find(20);//在n节点后面添加一个15的值的节点linkedList.AddAfter(n, 15);//4.在某一个节点之前添加一个节点//  要指定节点 先得得到一个节点linkedList.AddBefore(n, 11);

//1.移除头节点
linkedList.RemoveFirst();
//2.移除尾节点
linkedList.RemoveLast();
//3.移除指定节点
//  无法通过位置直接移除
linkedList.Remove(20);
//4.清空
linkedList.Clear();linkedList.AddLast(1);
linkedList.AddLast(2);
linkedList.AddLast(3);
linkedList.AddLast(4);

//1.头节点
LinkedListNode<int> first = linkedList.First;
//2.尾节点
LinkedListNode<int> last = linkedList.Last;
//3.找到指定值的节点
//  无法直接通过下标获取中间元素
//  只有遍历查找指定位置元素
LinkedListNode<int> node = linkedList.Find(3);
Console.WriteLine(node.Value);
node = linkedList.Find(5);
//4.判断是否存在
if( linkedList.Contains(1) )
{Console.WriteLine("链表中存在1");
}

//要先得再改 得到节点 再改变其中的值
Console.WriteLine(linkedList.First.Value);
linkedList.First.Value = 10;
Console.WriteLine(linkedList.First.Value);

遍历

//1.foreach遍历
foreach (int item in linkedList)
{Console.WriteLine(item);
}//2.通过节点遍历
//  从头到尾
Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&");
LinkedListNode<int> nowNode = linkedList.First;
while (nowNode != null)
{Console.WriteLine(nowNode.Value);nowNode = nowNode.Next;
}//  从尾到头Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&");
nowNode = linkedList.Last;
while (nowNode != null)
{Console.WriteLine(nowNode.Value);nowNode = nowNode.Previous;
}

练习

使用Linkedlist,向其中加入10个随机整形变量
正向遍历一次打印出信息

反向遍历一次打印出信息

数据容器

变量

无符号
byte ushort uint ulong
有符号
sbyte short int long
浮点数
float double decimal
特殊
char bool string

复杂数据容器

枚举 enum
结构体 struct
数组(一维、二维、交错) []  [,]  [][]
类

数据集合

using System.Collections;ArrayList object数据列表
Stack 栈  先进后出
Queue 队列 先进先出
Hashtable 哈希表  键值对

泛型数据集合

using System.Collections.Generic;List 列表  泛型列表
Dictionary 字典 泛型哈希表
LinkedList 双向链表
Statck 泛型栈
Queue 泛型队列

泛型栈和队列

//命名空间:using System.Collections.Generic;
//使用上 和之前的Stack和Queue一模一样
Stack<int> stack = new Stack<int>();
Queue<object> queue = new Queue<object>();

如何使用数据容器

数组、List、Dictionary、Stack、Queue、LinkedList
这些存储容器,对于我们来说应该如何选择他们来使用

普通线性表:
数组,List,LinkedList
数组:固定的不变的一组数据
List: 经常改变,经常通过下标查找
LinkedList:不确定长度的,经常临时插入改变,查找不多先进后出:
Stack
对于一些可以利用先进后出存储特点的逻辑
比如:UI面板显隐规则先进先出:
Queue
对于一些可以利用先进先出存储特点的逻辑
比如:消息队列,有了就往里放,然后慢慢依次处理键值对:
Dictionary
需要频繁查找的,有对应关系的数据
比如一些数据存储  id对应数据内容
道具ID ——> 道具信息
怪物ID ——> 怪物对象
等等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/5570.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

书生大模型实战营Linux+InternStudio 关卡任务

一、端口映射 使用以下命令进行端口映射 ssh -p {YOUR_PORT} rootssh.intern-ai.org.cn -CNg -L 7860:127.0.0.1:7860 -o StrictHostKeyCheckingno 命令解释&#xff1a; -p 37367&#xff1a;是指定 SSH 连接的端口为 37367。rootssh.intern-ai.org.cn&#xff1a;表示要以…

道品科技智能水肥一体化技术要点及实施效果

## 一、引言 水肥一体化技术是现代农业中一种重要的耕作方式&#xff0c;旨在通过合理配置水资源与肥料&#xff0c;提高作物产量和质量&#xff0c;达到节水、增效和环保的目的。随着全球人口的增加和耕地资源的减少&#xff0c;水肥一体化技术在农业生产中的应用愈加重要。 …

sqlserver使用bak文件恢复数据库

进入数据库 sqlcmd -S localhost -U SA -P password备份文件 #备份格式BACKUP DATABASE your_database_name TO DISK path_to_backup_file.bak;#举例 1> BACKUP DATABASE XJZDataTest TO DISK /root/mssql.bak; 2> go使用备份文件恢复数据库 1、查询备份文件中的数据…

CSP/信奥赛C++刷题训练:经典深搜例题(1):洛谷1605 :迷宫

CSP/信奥赛C刷题训练&#xff1a;经典深搜例题&#xff08;1&#xff09;&#xff1a;洛谷1605 &#xff1a;迷宫 题目描述 给定一个 N M N \times M NM 方格的迷宫&#xff0c;迷宫里有 T T T 处障碍&#xff0c;障碍处不可通过。 在迷宫中移动有上下左右四种方式&#x…

yolov8涨点系列之Concat模块改进

文章目录 Concat模块修改步骤(1) BiFPN_Concat3模块编辑(2)在__init_.pyconv.py中声明&#xff08;3&#xff09;在task.py中声明yolov8引入BiFPN_Concat3模块yolov8.yamlyolov8.yaml引入C2f_up模块 在YOLOv8中&#xff0c; concat模块主要用于将多个特征图连接在一起。其具体…

越权访问漏洞

V2Board Admin.php 越权访问漏洞 ## 漏洞描述 V2board面板 Admin.php 存在越权访问漏洞&#xff0c;由于部分鉴权代码于v1.6.1版本进行了修改&#xff0c;鉴权方式变为从Redis中获取缓存判定是否存在可以调用… V2Board Admin.php 越权访问漏洞 漏洞描述 V2board面板 Admin.ph…

安装和运行开发微信小程序

下载HBuilder uniapp官网 uni-app官网 微信开发者工具 安装 微信小程序 微信小程序 官网 微信小程序 配置 运行 注意&#xff1a;运行前需要开启服务端口 如果运行看不到效果&#xff0c;设置下基础库选别的版本 配置

小檗碱和卤代苄基异喹啉生物碱的代谢工程合成-文献精读79

De novo biosynthesis of berberine and halogenated benzylisoquinoline alkaloids in Saccharomyces cerevisiae 在 酿酒酵母&#xff08;Saccharomyces cerevisiae&#xff09;中从头合成小檗碱和卤代苄基异喹啉生物碱 小檗碱的酵母代谢工程生物合成-文献精读78 苄基异喹…

鸿蒙开发案例:七巧板

【1】引言&#xff08;完整代码在最后面&#xff09; 本文介绍的拖动七巧板游戏是一个简单的益智游戏&#xff0c;用户可以通过拖动和旋转不同形状的七巧板块来完成拼图任务。整个游戏使用鸿蒙Next框架开发&#xff0c;利用其强大的UI构建能力和数据响应机制&#xff0c;实现了…

【TS】九天学会TS语法——1.TypeScript 是什么

今天学习的是TypeScript 基础&#xff0c;目标是了解 TypeScript 的基本概念&#xff0c;安装 TypeScript&#xff0c;编写第一个 TypeScript 程序。 TypeScript 简介安装 TypeScriptTypeScript 编译过程编写第一个 TypeScript 程序 随着前端开发的不断发展&#xff0c;TypeScr…

Docker学习—Docker的安装与使用

Docker安装 1.卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2.配置Docker的yum库 首先…

69.ov5640摄像头HDMI灰度显示

&#xff08;1&#xff09;理论学习 灰度像素&#xff1a;在 RGB 颜色模型下&#xff0c;图像中每个像素颜色的 R、G、B 三种基色的分量值相等的像素。由灰度像素组成的灰度图像只能表现256中颜色&#xff08;或亮度&#xff09;&#xff0c;通常把灰度图像中像素的亮度称为灰…

Star Tower:开启数据存储新纪元

在科技飞速发展的当今时代&#xff0c;数据如同璀璨的星辰&#xff0c;闪耀着无尽的价值。而数据存储系统&#xff0c;则是承载这些星辰的浩瀚宇宙。Star Tower 以其卓越的性能和创新的理念&#xff0c;开启了数据存储的新纪元。 Star Tower 的分布式存储架构&#xff0c;是一…

基于SSM的企业管理系统(源码+lw+调试+技术指导)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

鸿蒙应用App测试-通用测试

注意&#xff1a;大家记得学完通用测试记得再学鸿蒙专项测试 鸿蒙应用App测试-专项测试&#xff08;DevEco Testing&#xff09;-CSDN博客 注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得…

掌握Qt调试技术

文章目录 前言一、Qt调试的基本概念二、Qt调试工具三、Qt调试实践四、Q调试技巧五、总结前言 在软件开发中,调试是一个至关重要的环节。Qt作为一个广泛使用的跨平台C++图形用户界面应用程序开发框架,其调试技术也显得尤为重要。本文将深入探讨Qt调试技术,帮助读者更好地掌握…

Qt中时间戳转化为时间

QT中时间和时间戳互相转化_currentsecssinceepoch-CSDN博客 qDebug()<<QDateTime::currentMSecsSinceEpoch(); 1730838034770 时间戳(Unix timestamp)转换工具 - 在线工具 (tool.lu) [static] qint64 QDateTime::currentMSecsSinceEpoch() Returns the number of milli…

势不可挡 创新引领 | 生信科技SOLIDWORKS 2025新品发布会·苏州站精彩回顾

2024年11月01日&#xff0c;由生信科技举办的SOLIDWORKS 2025新产品发布会在江苏苏州圆满落幕。现场邀请到制造业的专家学者们一同感受SOLIDWORKS 2025最新功能&#xff0c;探索制造业数字化转型之路。 在苏州站活动开场&#xff0c;达索系统专业客户事业部华东区渠道经理马腾飞…

ArcGIS006:ArcMap常用操作151-200例动图演示

摘要&#xff1a;本文介绍了ArcMap邻域分析、栅格表面分析、水文分析、区域分析、提取分析等工具箱中的工具功能。包括计算图层间点、线、面要素间的距离、位置和角度&#xff0c;创建缓冲区&#xff0c;添加计算信息到属性表&#xff0c;分割面要素&#xff0c;编号&#xff0…

关于马达驱动芯片AT6237的开发指南(兼容DRV8837)

一、芯片引脚介绍 1.芯片引脚 二、系统结构图 三、功能描述 逻辑功能