C# 集合分析

几种常见的数据结构:

线性数据结构,典型的有:数组、栈、队列和线性表

【LinkedList<T>】

链表,在存储元素时,不仅要存储元素的值,还必须存储每个元素的下一个元素和上一个元素的信息。

优点:如果将元素插入到列表的中间位置,使用链表就会很快。在插入一个元素时,只需要修改上一个元素的 Next 引用和下一个元素的 Previous 引用,使它们引用所插入的元素。而在 List<T> 中插入一个元素,需要移动该元素后面的所以元素。

缺点:链表元素只能一个接一个的访问,这需要较长时间来查找位于链表中间或尾部的元素。

  First()、Last():访问链表中的第一个和最后一个元素

  AddAfter()、AddFirst、AddLast():在指定位置插入元素

  Remove(),RemoveFirst()、RemoveLast():删除指定位置的元素

  Find()、FindLast():搜索

【Queue】

队列,采用先入先出机制(FLFO, First in First out),不允许直接对队列中非队头元素进行访问和删除,不允许在中间的某个位置插入。

使用:

  Count:返回队列中的元素个数

  Enqueue():在队列的末端添加元素

  Dequeue():在队列的头部读取和删除一个元素。注意,这里读取元素的同时也删除了这个元素。如果队列中不再有任何元素,就抛出异常

  Peek():在队列的头读取一个元素,但是不删除它

  TrimExcess():重新设置队列的容量,因为调用Dequeue方法读取删除元素后不会重新设置队列的容量

  Contains():确定某个元素是否在队列中

  CopyTo():把队列复制到一个已有的数组中

  ToArray():把队列复制到新数组

  Clear():从队列中移除所有对象

声明:

Queue<object> queueData = new Queue<object>();

延伸:

ConcurrentQueue,对线程做了安全处理:https://www.cnblogs.com/zpy1993-09/p/13525421.html

【Array】

数组,它在内存中是连续存储的,所以索引速度很快,而且赋值与修改元素也很简单。

string[] s = new string[3];
//赋值
s[0]="a";
s[1]="b";
s[2]="c";
//修改
s[1]="b1";
//获取元素数量
int length = s.Length;

其他声明方式:定义数组并初始化(也是指明了数组长度)。

string[] array1 = new string[] { "张三", "李四", "王五", "曾静" }; 
string[] array2 = { "张三", "李四", "王五", "曾静" }; 

由于数组不能更改长度,所以增加和删除元素只能重新定义数组。

//例如新增元素,我们这里用CopyTo方法来将原来的数组Copy到一个新数组中。
string[] news = new string[4];
s.CopyTo(news, 0);
news[3] = "d";
//移除和插入的话,使用for遍历原来的数组赋值给新数组。
//for(int i……

缺点:根据内容查找元素速度慢;只能存储一种类型的数据;声明数组时必须指明数组长;增加和删除元素效率慢
改善:ArrayList


【ArrayList】

动态数组,专门用于存储异类对象的集合。可以存多种数据类型,不需要指定它的长度,很方便的进行数据的添加,插入和移除

ArrayList list = new ArrayList();
//新增数据
list.Add("abc");
list.Add(123);
list.Add("张三");
//修改数据
list[1] = 345;
//移除数据
list.Remove("张三");
//根据索引移除和插入数据
list.RemoveAt(0);
list.Insert(0, "hello world");
//取值(必须进行数据类型转换)
string str = (string)list[1];
//获取元素数量
int count = list.Count;

其他方法:

  Clear():清除全部元素

  Reverse():反转数组的元素

  Sort():以从小到大的顺序排列数组的元素

缺点:

  因为可存不同类型的数据,所以插入的数据都是当做 object 类型来处理。

  那我们在取值的时候,进行错误的类型转换也能通过编译,那么就会报类型不匹配的错误;而且必须的类型转换存在了装箱和拆箱的操作,增加性能损耗

改善:泛型List<T>

【泛型 List<T>】

 为解决 ArrayList 存在不安全类型与装箱拆箱(额外耗费cpu和内存资源)的缺点,所以在 C# 2.0 之后引入了泛型。T为列表中元素类型,现在以 string 类型作为例子。

//创建一个普通的泛型集合类
List<string> list = new List<string>();
//新增数据
list.Add("张三");
//修改数据
list[0] = "李四";
//移除数据
list.Remove("李四");

List<T> 虽然排除了不安全类型的隐患,但是也限制了存储数据的类型。如果要存储异类对象的集合,可以用 List<object>;

小结:上述经过比较,数组用于保存固定数量的数据,定长,占用内存少,遍历速度快; 集合保存的数据数量,可以在程序的执行过程中,不断发生变化,不定长,占用内存多,遍历速度慢;在功能上,数组能实现的所有功能,集合都能实现;反之,集合能实现的某些功能,数组难以实现。


【HashTable】

哈希表,键值对存储 object 类型,所以支持任何类型的键值对;使用时需要强制转换;key分大小写。

//实例化Hashtable
Hashtable hashTable = new Hashtable();
//增加元素
hashTable.Add("姓名", "小芳");
hashTable.Add("性别", "");
hashTable.Add("年龄", 28);
//遍历哈希表
foreach (DictionaryEntry item in hashTable)
{
  Console.WriteLine("哈希键:" + item.Key + ",哈希值:" + item.Value.ToString());
} 
//遍历键or值
foreach (object value in hashTable.Values)
{
  Console.WriteLine(value);
}
//删除元素
hashTable.Remove("性别");
//元素个数
int count = hashTable.Count;
//取值
string name = (string)hashTable["姓名"];
int age = (int)hashTable["年龄"];
//删除所有元素
hashTable.Clear();
//判断是否包含key
bool isKey = hashTable.ContainsKey("姓名");
//判断是否包含value
bool isValue = hashTable.ContainsValue("小芳");


【Dictionary】

字典,键值对集合,拥有键和值两种类型,支持 Add 和 Remove,满足键值条件的数据集合。

//创建及初始化
Dictionary<int, string> myDictionary = new Dictionary<int, string>();

//添加元素
myDictionary.Add(1, "C#");
myDictionary.Add(2, "C++");
myDictionary.Add(3, "ASP.NET");
myDictionary.Add(4, "MVC");
//通过Key查找元素
if (myDictionary.ContainsKey(1))
{
  Console.WriteLine("Key:{0},Value:{1}", "1", myDictionary[1]);
}
//通过KeyValuePair遍历元素
foreach (KeyValuePair<int, string> kvp in myDictionary)
{
  Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
//仅遍历键 Keys 属性
Dictionary<int, string>.KeyCollection keyCol = myDictionary.Keys;
foreach (int key in keyCol)
{
  Console.WriteLine("Key = {0}", key);
} 
//仅遍历值 Values 属性
Dictionary<int, string>.ValueCollection valueCol = myDictionary.Values;
foreach (string value in valueCol)
{
  Console.WriteLine("Value = {0}", value);
}
//通过Remove方法移除指定的键值
myDictionary.Remove(1);

其他方法:

  Count():获取键/值对的数目  

  Clear():移除所有的键和值

延伸:

ConcurrentDictionary,对线程做了安全处理。详细

 SortedDictionary,字典序排序。

ArrayList、List、Hashtable、Dictionary 的联系与区别:

类别    
Arraylist 可以添加数据,数据的个数不受限制 需要导入命名空间,存的数据不限制类型
List 可以添加数据,数据的个数不受限制 不用导入命名空间,确定了存数据的类型
Hashtable 以键值对的形式存值,方法很相似 需要导入命名空间,存的数据不限制类型
dictionary 以键值对的形式存值,方法很相似 不用导入命名空间,确定了存数据的类型

小结:我认为应该始终使用 Dictionary<K, V>,即使要用 Hashtable 了,也可以用 Dictionary<object, object> 来替代。

 

【DataTable】

https://www.cnblogs.com/qianqian528/p/8456351.html

 

 

转载于:

https://www.cnblogs.com/AduBlog/p/13624292.html

https://blog.csdn.net/weixin_44870681/article/details/92068543

原文地址:https://www.cnblogs.com/Allofus/p/10208164.html