在本文中,我们使用C#集合。集合是专门用于数据存储和检索的类。
C#中有三种不同的集合类型:
- 标准
- 通用
- 并发
标准集合位于System.Collections下。它们不将元素存储为特定类型的对象,而是存储为Object类型的对象。标准集合包括ArrayList、Hashtable、Queue和Stack。
通用集合位于System.Collections.Generic下。通用集合更灵活,是处理数据的首选方式。泛型增强代码重用、类型安全和性能。泛型集合包括Dictionary、List、Queue、SortedList和Stack。
并发集合包括BlockingCollection、ConcurrentDictionary、ConcurrentQueue和ConcurrentStack.
C#列表
List是一个可以通过索引访问的对象的强类型列表。它可以在System.Collections.Generic命名空间下找到。该命名空间自动包含在隐式使用中。
var langs = new List<string>();
langs.Add("Java");
langs.Add("C#");
langs.Add("C");
langs.Add("C++");
langs.Add("Ruby");
langs.Add("Javascript");
Console.WriteLine(langs.Contains("C#"));
Console.WriteLine(langs[1]);
Console.WriteLine(langs[2]);
langs.Remove("C#");
langs.Remove("C");
Console.WriteLine(langs.Contains("C#"));
langs.Insert(4, "Haskell");
langs.Sort();
foreach (string lang in langs)
{
Console.WriteLine(lang);
}
在前面的示例中,我们使用List集合。
using System.Collections.Generic;
List集合位于System.Collections.Generic命名空间中。
var langs = new List<string>();
创建了一个通用动态数组。我们指定我们使用字符内指定类型的字符串。
langs.Add("Java");
langs.Add("C#");
langs.Add("C");
...
我们使用Add方法向List添加元素。
Console.WriteLine(langs.Contains("C#"));
我们使用Contains方法检查List是否包含特定字符串。
Console.WriteLine(langs[1]); Console.WriteLine(langs[2]);
我们使用索引符号访问List的第二个和第三个元素。
langs.Remove("C#");
langs.Remove("C");
我们从列表中删除两个字符串。
langs.Insert(4, "Haskell");
我们在特定位置插入一个字符串。
langs.Sort();
我们使用Sort方法对元素进行排序。
$ dotnet run True C# C False C++ Haskell Java Javascript Ruby
C#数组列表
ArrayList是来自标准System.Collections命名空间的集合。它是一个动态数组。它提供对其元素的随机访问。添加数据时,ArrayList会自动扩展。与数组不同,ArrayList可以保存多种数据类型的数据。ArrayList中的元素通过整数索引访问。索引是从零开始的。ArrayList末尾的元素索引以及插入和删除需要常数时间。在动态数组中间插入或删除元素的成本更高。它需要线性时间。
using System.Collections;
var data = new ArrayList();
data.Add("Visual Basic");
data.Add(344);
data.Add(55);
data.Add(new Empty());
data.Remove(55);
foreach (object el in data)
{
Console.WriteLine(el);
}
class Empty {}
在上面的示例中,我们创建了一个ArrayList集合。我们向其中添加了一些元素。它们有各种数据类型,字符串,int和类对象。
using System.Collections;
为了使用ArrayList集合,我们需要使用System.Collections命名空间。
var data = new ArrayList();
ArrayList集合被创建。
data.Add("Visual Basic");
data.Add(344);
data.Add(55);
data.Add(new Empty());
data.Remove(55);
我们使用Add方法向数组添加四个元素。
data.Remove(55);
我们使用Remove方法删除一个元素。
foreach(object el in data)
{
Console.WriteLine(el);
}
我们遍历数组并将其元素打印到控制台。
$ dotnet run Visual Basic 344 Empty
C#集合初始化器
集合初始值设定项允许在{}括号中的对象创建期间为集合指定元素。
var vals = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
int sum = vals.Sum();
Console.WriteLine(sum);
该示例创建一个列表并打印其总和。列表的元素在集合初始值设定项中指定。
$ dotnet run 28
C#排序列表
SortedList表示已排序的键/值对的集合。
var sorted = new SortedList<string, int>();
sorted.Add("coins", 3);
sorted.Add("books", 41);
sorted.Add("spoons", 5);
if (sorted.ContainsKey("books"))
{
Console.WriteLine("There are books in the list");
}
foreach (var pair in sorted)
{
Console.WriteLine(pair);
}
该示例使用排序列表来组织项目。
var sorted = new SortedList<string, int>();
排序后的列表有字符串键和整数值。
if (sorted.ContainsKey("books"))
{
Console.WriteLine("There are books in the list");
}
使用ContainsKey,我们检查集合中是否有书。
foreach (var pair in sorted)
{
Console.WriteLine(pair);
}
使用foreach循环,我们遍历集合并打印它的对。
$ dotnet run There are books in the list [books, 41] [coins, 3] [spoons, 5]
C#链表
LinkedList是C#中的通用双向链表。链表只允许顺序访问。LinkedList允许常量时间插入或删除,但只能顺序访问元素。因为链表需要额外的存储空间来存储引用,所以它们对于字符等小数据项的列表是不切实际的。
与动态数组不同,可以将任意数量的项目添加到链表(当然受内存限制)而无需重新分配,这是一种昂贵的操作。
var nums = new LinkedList<int>();
nums.AddLast(23);
nums.AddLast(34);
nums.AddLast(33);
nums.AddLast(11);
nums.AddLast(6);
nums.AddFirst(9);
nums.AddFirst(7);
LinkedListNode<int> node = nums.Find(6);
nums.AddBefore(node, 5);
foreach (int num in nums)
{
Console.WriteLine(num);
}
这是一个LinkedList示例及其一些方法。
var nums = new LinkedList<int>();
这是一个整数LinkedList。
nums.AddLast(23); ... nums.AddFirst(7);
我们使用AddLast和AddFirst方法填充链表。
LinkedListNode<int> node = nums.Find(6); nums.AddBefore(node, 5);
LinkedList由节点组成。我们找到一个特定的节点并在它之前添加一个元素。
foreach(int num in nums)
{
Console.WriteLine(num);
}
我们正在将所有元素打印到控制台。
$ dotnet run 7 9 23 34 33 11 5 6
C#字典
字典,也称为关联数组,是唯一键和值的集合,其中每个键都与一个值相关联。检索和添加值非常快。字典占用更多内存,因为每个值都有一个键。
var domains = new Dictionary<string, string>();
domains.Add("de", "Germany");
domains.Add("sk", "Slovakia");
domains.Add("us", "United States");
domains.Add("ru", "Russia");
domains.Add("hu", "Hungary");
domains.Add("pl", "Poland");
Console.WriteLine(domains["sk"]);
Console.WriteLine(domains["de"]);
Console.WriteLine("Dictionary has {0} items", domains.Count);
Console.WriteLine("Keys of the dictionary:");
var keys = new List<string>(domains.Keys);
foreach (string key in keys)
{
Console.WriteLine("{0}", key);
}
Console.WriteLine("Values of the dictionary:");
var vals = new List<string>(domains.Values);
foreach (string val in vals)
{
Console.WriteLine("{0}", val);
}
Console.WriteLine("Keys and values of the dictionary:");
foreach (KeyValuePair<string, string> kvp in domains)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
我们有一本字典,我们将域名映射到他们的国家/地区名称。
var domains = new Dictionary<string, string>();
我们创建一个包含字符串键和值的字典。
domains.Add("de", "Germany");
domains.Add("sk", "Slovakia");
domains.Add("us", "United States");
...
我们向字典中添加一些数据。第一个字符串是密钥。二是价值。
Console.WriteLine(domains["sk"]); Console.WriteLine(domains["de"]);
这里我们通过键检索两个值。
Console.WriteLine("Dictionary has {0} items", domains.Count);
我们通过引用Count属性打印项目数。
var keys = new List<string>(domains.Keys);
foreach(string key in keys)
{
Console.WriteLine("{0}", key);
}
这些行从字典中检索所有键。
var vals = new List<string>(domains.Values);
foreach(string val in vals)
{
Console.WriteLine("{0}", val);
}
这些行从字典中检索所有值。
foreach(KeyValuePair<string, string> kvp in domains)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
最后,我们打印字典的键和值。
$ dotnet run Slovakia Germany Dictionary has 6 items Keys of the dictionary: de sk us ru hu pl Values of the dictionary: Germany Slovakia United States Russia Hungary Poland Keys and values of the dictionary: Key = de, Value = Germany Key = sk, Value = Slovakia Key = us, Value = United States Key = ru, Value = Russia Key = hu, Value = Hungary Key = pl, Value = Poland
C#队列
queue是一种先进先出(FIFO)数据结构。添加到队列中的第一个元素将是第一个被删除的元素。队列可用于在消息出现时对其进行处理或在客户到来时为其提供服务。第一个来的顾客应该首先得到服务。
var msgs = new Queue<string>();
msgs.Enqueue("Message 1");
msgs.Enqueue("Message 2");
msgs.Enqueue("Message 3");
msgs.Enqueue("Message 4");
msgs.Enqueue("Message 5");
Console.WriteLine(msgs.Dequeue());
Console.WriteLine(msgs.Peek());
Console.WriteLine(msgs.Peek());
Console.WriteLine();
foreach (string msg in msgs)
{
Console.WriteLine(msg);
}
在我们的示例中,我们有一个包含消息的队列。
var msgs = new Queue<string>();
创建了一个字符串队列。
msgs.Enqueue("Message 1");
msgs.Enqueue("Message 2");
...
Enqueue将消息添加到队列的末尾。
Console.WriteLine(msgs.Dequeue());
Dequeue方法移除并返回队列开头的项目。
Console.WriteLine(msgs.Peek());
Peek方法返回队列中的下一个项目,但不会将其从集合中移除。
$ dotnet run Message 1 Message 2 Message 2 Message 2 Message 3 Message 4 Message 5
Dequeue方法从集合中删除“消息1”。Peek方法没有。“消息2”保留在集合中。
C#堆栈
堆栈是一种后进先出(LIFO)数据结构。添加到队列中的最后一个元素将是第一个被删除的元素。C语言在函数中使用astack来存储本地数据。在实现计算器时也使用堆栈。
var myStack = new Stack<int>();
myStack.Push(1);
myStack.Push(4);
myStack.Push(3);
myStack.Push(6);
myStack.Push(4);
Console.WriteLine(myStack.Pop());
Console.WriteLine(myStack.Peek());
Console.WriteLine(myStack.Peek());
Console.WriteLine();
foreach (int item in myStack)
{
Console.WriteLine(item);
}
我们上面有一个简单的堆栈示例。
var myStack = new Stack<int>();
创建了一个Stack数据结构。
myStack.Push(1); myStack.Push(4); ...
Push方法在堆栈顶部添加一个项目。
Console.WriteLine(stc.Pop());
Pop方法从堆栈顶部移除并返回项目。
Console.WriteLine(myStack.Peek());
Peek方法返回堆栈顶部的项目。它不会删除它。
$ dotnet run 4 6 6 6 3 4 1
在本文中,我们使用了C#中的集合。
列出所有C#教程。
