数组是存储固定大小的数据集合。可以是一维数组,多维数组。
在存储数据量较小,并且不需改变的时使用比较多。
string[] weekdays = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };//直接初赋值 int[] amounts = new int[10]; //限定数组长度,int类型则默认为0 string wednesday = weekdays[2]; //通过下标索引获取对应的值 int weekdaysLength = weekdays.Length; //数组的Length属性可得到当前数组的长度 //使用迭代器遍历,正常情况下都是使用for或者foreach进行遍历,这里只是示例 var enumerator = amounts.GetEnumerator(); while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current.ToString()); } int[,] sizes = new int[4, 3]; //声明二维数组4*3 int[,] packageSizes = new int[,] { { 5,5,6},{3,4,5 } };//声明二维数组并直接初赋值
ArrayList是线性结构、非泛型集合(动态数组)。
这类集合还是比较少用的,基本上都是使用对应的泛型集合(List)。
ArrayList tmpArrayList = new ArrayList(); //添加元素,不限制数据类型,继承object的都可以.值类型数据默认会进行装箱操作 tmpArrayList.Add("多线程"); tmpArrayList.Add(100); tmpArrayList.AddRange(new int[] { 89, 92, 86,100,100 }); //通过下标获取数据 var firstElement = tmpArrayList[0]; //获取指定连续的数据 ArrayList newArray= tmpArrayList.GetRange(1,4); int length = tmpArrayList.Count; //获取动态数组的总的元素个数 //删除操作 tmpArrayList.RemoveAt(3); tmpArrayList.Remove(100);//移除第一个匹配的项 foreach (var item in tmpArrayList) { Console.WriteLine(item.ToString()); } //tmpArrayList.Sort(); //排序,此处会报错,因为第一个为字符串类型,不支持排序 tmpArrayList.Reverse();//反转 tmpArrayList.Clear();//清空
List是线性结构的泛型集合。
这是我们开发中经常用到的一种集合。存储没有太多增删操作的无序列表(一般都是用于临时存储,用于数据检索过滤的,我们还经常会用到的是list基于linq的查询)。
LinkedList是线性结构双向链表。
较少使用,主要用于频繁增、元素的情况下。
以下是简单实现一个链表,仅作参考,如需详细了解net的链表实现还请查看其源码
public class CustomerLinkedNode<T> { /// <summary> /// 当前值 /// </summary> public T Value { get; set; } /// <summary> /// 前驱 /// </summary> public CustomerLinkedNode<T> Privious { get; set; } /// <summary> /// 后续 /// </summary> public CustomerLinkedNode<T> Next { get; set; } } public class CustomerLinkedList<T> { private int count = 0; public int Count { get { return count; } } private CustomerLinkedNode<T> first; /// <summary> /// 首项值 /// </summary> public T First { get { if (first == null) { return default(T); } else { return first.Value; } } } private CustomerLinkedNode<T> last; /// <summary> /// 尾项值 /// </summary> public T Last { get { if (last == null) { return default(T); } else { return last.Value; } } } /// <summary> /// 添加为首项 /// </summary> /// <param name="item"></param> public void AddFirst(T item) { if (first == null) { first = new CustomerLinkedNode<T>() { Value = item, Next = null, Privious = null, }; last = first; } else { var newFirst = new CustomerLinkedNode<T>() { Value = item, Next = first, Privious = null, }; first.Privious = newFirst; first = newFirst; } count++; } /// <summary> /// 添加为尾项 /// </summary> /// <param name="item"></param> public void AddLast(T item) { if (first == null) { //链表为空时,first=last first = new CustomerLinkedNode<T>() { Value = item, Next = null, Privious = null, }; last = first; } else { var newLast = new CustomerLinkedNode<T>() { Value = item, Next = null, Privious = last, }; last.Next = newLast; last = newLast; } count++; } /// <summary> /// 指定索引前部添加 /// </summary> /// <param name="index"></param> /// <param name="item"></param> public void AddBefore(int index, T item) { if (index < 0 || index > count - 1) { throw new Exception("索引超出"); } if (index == 0) { AddFirst(item); return; } var newNode = new CustomerLinkedNode<T> { Value = item, }; int tmpIndex = 0; for (var node = first; node != null; node = node.Next) { if (tmpIndex == index) { node.Privious.Next = newNode; newNode.Privious = node.Privious; newNode.Next = node; node.Privious = newNode; count++; break; } tmpIndex++; } } /// <summary> /// 指定索引后部添加 /// </summary> /// <param name="index"></param> /// <param name="item"></param> public void AddAfter(int index, T item) { if (index < 0 || index > count - 1) { throw new Exception("索引超出"); } if (index == count - 1) { AddLast(item); return; } var newNode = new CustomerLinkedNode<T> { Value = item, }; int tmpIndex = 0; for (var node = first; node != null; node = node.Next) { if (tmpIndex == index) { newNode.Privious = node; newNode.Next = node.Next; node.Next.Privious = newNode; node.Next = newNode; count++; break; } tmpIndex++; } } //引用类型不能简单的使用==进行判断是否是同一对象,暂不实现 ///// <summary> ///// 移除第一个匹配的项 ///// </summary> ///// <param name="t"></param> //public bool Remove(T t) //{ // for (var node = first; node != null; node = node.Next) // { // if (node.Value == t) // { // } // } //} /// <summary> /// 移除指定索引项 /// </summary> /// <param name="index"></param> /// <returns></returns> public bool RemoveAt(int index) { if (index < 0 || index > count - 1) { throw new Exception("索引超出"); } int tmpIndex = 0; for (var node = first; node != null; node = node.Next) { if (tmpIndex == index) { if (node.Privious != null) { node.Privious.Next = node.Next; } if (node.Next != null) { node.Next.Privious = node.Privious; } count--; break; } tmpIndex++; } return true; } /// <summary> /// 清空 /// </summary> public void Clear() { this.count = 0; first = null; last = null; } }
ConcurrentBag是线程安全的线性结构的泛型集合。
内部实现可参照https://www.cnblogs.com/InCerry/p/9497729.html
主要用于多线程操作列表的情况下
在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于存储、处理key-value的键值对。
Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的key-value键值对。所以在处理值类型数据时,会涉及装/拆箱操作
在开发过程中,.net的hashtable其实用的不是很多。我们更多的是使用支持泛型结构的Dictionary
简单的代码示例,无意义 var tmpHashtable = new Hashtable(); tmpHashtable.Add("广州","GZ"); tmpHashtable.Add("北京", "BJ"); tmpHashtable.Add("深圳","SZ"); tmpHashtable.Add("上海","SH"); var szCode = tmpHashtable["深圳"]; //获取指定键的值 //遍历 foreach (DictionaryEntry item in tmpHashtable) { Console.WriteLine(item.Value.ToString()); } if (tmpHashtable.ContainsKey("北京")) { //TODO something } tmpHashtable.Remove("广州"); //移除 //...
dictionay(字典)是支持泛型的键值对集合
ConcurrentDictionary 线程安全的数据字典结构。(很少使用,略)
队列是先进先出的数据集合。
Queue<SaleOrder> orderQueue = new Queue<SaleOrder>(); //入队 orderQueue.Enqueue(new SaleOrder() { Id = Guid.NewGuid(), OrderDate=new DateTime(2020,11,11), OrderNumber="A00008901", }) ; orderQueue.Enqueue(new SaleOrder() { Id = Guid.NewGuid(), OrderDate = new DateTime(2020, 11, 11), OrderNumber = "A00008902", }); orderQueue.Enqueue(new SaleOrder() { Id = Guid.NewGuid(), OrderDate = new DateTime(2020, 12, 1), OrderNumber = "A00008903", }); //遍历队列 foreach (var item in orderQueue) { Console.WriteLine(item); } var order=orderQueue.Dequeue();//出队(获取值并删除),也可以使用TryDequeue方法 Console.WriteLine(order.OrderNumber); var secondOrder=orderQueue.Peek();//获取队首元素,不删除;也可以使用TryPeek方法 Console.WriteLine(secondOrder.OrderNumber);
ConcurrentQueue是线程安全的队列(很少使用,略)
Stack(栈)是一种先进后出的数据结构。
Stack<char> stack = new Stack<char>(); //压入栈 stack.Push(‘(‘); stack.Push(‘1‘); stack.Push(‘+‘); stack.Push(‘8‘); stack.Push(‘)‘); stack.Push(‘*‘); stack.Push(‘5‘); StringBuilder expressString = new StringBuilder(); //遍历栈元素 foreach (var item in stack) { expressString.Append(item.ToString()); } Console.WriteLine(expressString); var val1 = stack.Pop();//弹出栈(同时删除该数据),也可使用TryPop方法 Console.WriteLine(val1.ToString()); var val2 = stack.Peek(); //获取栈顶数据,不删除。也可使用TryPeek方法 Console.WriteLine(val2.ToString());
ConcurrentStack线程安全的栈。(用的比较少,略)
原文:https://www.cnblogs.com/johnyong/p/14073294.html