现在各个集合类结合示例进行讲解:
一、泛型列表(List<T>)
1、声明语法及成员概要
class Program
{
static void Main(string[] args)
{
var intList = new List<int>(10); //创建特定类型的泛型列表
Console.WriteLine("Capacity: {0}", intList.Capacity); //列表容量
Console.WriteLine("Count: {0}", intList.Count); // 列表元素个数
intList.Capacity = 30;
Console.WriteLine("Capacity: {0}", intList.Capacity);
intList.TrimExcess(); //去除不需要的容量,但当元素达到容量90%时,TrimExcess()方法什么也不会做
Console.WriteLine("Capacity: {0}", intList.Capacity);
//集合初始值设定项等同于调用列表的Add()方法
var intList2 = new List<int>() { 1, 2 }; //集合初始值设定项只能在声明时使用
intList2.Add(3);
Console.WriteLine(intList2.Count);
Console.ReadLine();
}
}
2、列表的具体操作详解
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var hanmeimei = new Racer(2, "meimei", "han", "Brittain", 2);
var lilei = new Racer(5, "lei", "li", "America", 4);
var susan = new Racer(10, "leo", "susan", "Francio", 1);
var racers = new List<Racer>(20) { hanmeimei, lilei, susan };
racers.Add(new Racer(11, "le", "susa", "Francio", 3));
racers.Add(new Racer(23, "re", "nfd", "Russia", 3));
racers.AddRange(new Racer[] { new Racer(54, "ngsf", "an", "Brittain", 2) ,
new Racer(65, "ngf", "tre", "Brittain", 2) }); // AddRange()方法的参数IEnumerable<T>对象,所以可以传递一个数组
var racers1 = new List<Racer>(new Racer[] { new Racer(54, "ngsf", "an", "Brittain", 2) ,
new Racer(65, "ngf", "tre", "Brittain", 2) });
racers.Insert(3, new Racer(65, "ngf", "tre", "Brittain", 2)); //在制定位置插入元素
//列表的访问
var racer1 = racers[3];
for (int i = 0; i < racers.Count; i++)
Console.WriteLine(racers[i]);
foreach (Racer r in racers)
Console.WriteLine(r); //因为foreach 语句实现了IEnumerable接口
racers.ForEach(Console.WriteLine); // ForEach()将Action<T>作为参数, Console.WriteLine()方法的一个重载版本将object作为参数
racers.ForEach(r => Console.WriteLine("{0:A}", r)); //同上 lambda表达式,优点:可以传递格式
//删除(索引《更快》或者元素删除)
racers.RemoveAt(2);
if(!racers.Remove(hanmeimei)) //if(!racers.Remove(new Racer(5, "lei", "li", "America", 4)))因为Iequatable<T>和Object.equals()方法都没在racer类中重写,所以不能用要删除元素相同内容创建一个新对象,再把它传递给remove()方法
Console.WriteLine("Object can not found!");
racers.RemoveRange(2, 4);//参数1-索引, 参数2-元素个数
//查看元素是否存在,List<T>类提供了exist()方法;
racers.Exists(r => r.FirstName == "meimei");
//搜索
racers.IndexOf(hanmeimei); //找到返回索引,没找到返回-1
// 搜索指定特性的元素
int index = racers.FindIndex(r => r.Country == "America");
Racer r1 = racers.Find(r => r.FirstName == "NiKi");
Racer r2 = racers.FindLast(r => r.FirstName == "NiKi"); // 查找与Predicate<T>类型匹配的最后一项
//查找与Predicate<T>类型匹配的所有项
List<Racer> bigWinners = racers.FindAll(r => r.Wins > 3);
foreach (Racer r in bigWinners)
Console.WriteLine("{0:A}", r);
//排序
racers.Sort(); //可以不带参数,因为racer实现了IComparable<T>接口
Console.ReadLine();
racers.ForEach(Console.WriteLine);
racers.Sort(new RacerComparer(RacerComparer.CompareType.FirstName)); // RacerComparer已经实现了IComparer<T>接口
Console.ReadLine();
racers.ForEach(Console.WriteLine);
racers.Sort((x, y) => x.Wins.CompareTo(y.Wins)); // Comparison<T>是一个委托。注: public void List<T>.Sort(Comparison<T>).
Console.ReadLine();
racers.ForEach(Console.WriteLine);
racers.ForEach(r => Console.WriteLine("{0:A}", r)); //同上 lambda表达式
Console.ReadLine();
//逆转整个集合顺序
racers.Reverse();
racers.ForEach(r => Console.WriteLine("{0:A}", r)); //lambda表达式
// 类型转换
// ConvertAll<TOutput>() 方法使用一个converter委托,该委托定义如下
// public sealed delegate TOutput Converter<TInput, TOutput>(TInput from);
racers.ConvertAll<Person>(r => new Person(r.FirstName+ " " + r.LastName ));
//只读集合
using System;
using System.Collections.Generic;
public class Example
{
public static void Main()
{
List<string> dinosaurs = new List<string>(4);
Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity);
dinosaurs.Add("Tyrannosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Deinonychus");
Console.WriteLine();
foreach(string s in dinosaurs)
{
Console.WriteLine(s);
}
Console.WriteLine("\nIList<string> roDinosaurs = dinosaurs.AsReadOnly()");
IList<string> roDinosaurs = dinosaurs.AsReadOnly();
Console.WriteLine("\nElements in the read-only IList:");
foreach(string dinosaur in roDinosaurs)
{
Console.WriteLine(dinosaur);
}
Console.WriteLine("\ndinosaurs[2] = \"Coelophysis\"");
dinosaurs[2] = "Coelophysis";
Console.WriteLine("\nElements in the read-only IList:");
foreach(string dinosaur in roDinosaurs)
{
Console.WriteLine(dinosaur);
}
}
}
Console.ReadLine();
}
}
public class Racer : IComparable<Racer>, IFormattable
{
public Racer(int id, string firstName, string lastName, string country)
: this(id, firstName, lastName, country, 0)
{ }
public Racer(int id, string firstName, string lastName, string country, int wins)
{
this.ID = id;
this.FirstName = firstName;
this.LastName = lastName;
this.Country = country;
this.Wins = wins;
}
public int ID { get; private set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Country { get; set; }
public int Wins { get; set; }
public override string ToString()
{
return string.Format("{0} {1}", FirstName, LastName);
}
public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null)
return ToString();
switch (format.ToUpper())
{
case "N":
return ToString();
case "F":
return FirstName;
case "L":
return LastName;
case "C":
return string.Format("{0}, Country: {1}", ToString(), Country);
case "W":
return string.Format("{0}, Wins: {1}", ToString(), Wins);
case "A":
return string.Format("{0} {1} Wins: {2}", ToString(), ID, Wins);
default:
throw new FormatException(string.Format(formatProvider, "Format {} is not supported!", format));
}
}
public string Tostring(string format)
{
return ToString(format, null);
}
public int CompareTo(Racer other)
{
if (other == null) return -1;
int compare = string.Compare(this.LastName, other.LastName);
if (compare == 0)
compare = string.Compare(this.FirstName, other.FirstName);
return compare;
}
}
public class RacerComparer : IComparer<Racer>
{
public enum CompareType
{
FirstName,
LastName,
Country,
Wins
}
private CompareType compareType;
public RacerComparer(CompareType compareType)
{
this.compareType = compareType;
}
public int Compare(Racer x, Racer y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int result;
switch (compareType)
{
case CompareType.FirstName:
return string.Compare(x.FirstName, y.FirstName);
case CompareType.LastName:
return string.Compare(x.LastName, y.LastName);
case CompareType.Country:
result = string.Compare(x.Country, y.Country);
if (result == 0)
return string.Compare(x.LastName, y.LastName);
return result;
case CompareType.Wins:
return x.Wins.CompareTo(y.Wins);
default:
throw new ArgumentException("Invalid CompareType");
}
}
}
public class Person
{
public string name;
public Person(string name)
{
this.name = name;
}
public override string ToString()
{
return name;
}
}
}
二、队列
using System.Threading;
namespace Wrox
{
class Program
{
static void Main()
{
var dm = new DocumentManager();
ProcessDocument.Start(dm);
for (int i = 0; i < 1000; i++)
{
var doc = new Document("Doc." + i.ToString(), "content");
dm.AddDocument(doc);
Console.WriteLine("Add document: {0}", doc.Title);
Thread.Sleep(new Random().Next(20));
}
Console.ReadLine();
}
}
public class Document
{
public string Title { get; private set; }
public string Content { get; private set; }
public Document(string title, string content)
{
this.Title = title;
this.Content = content;
}
}
public class DocumentManager
{
private readonly Queue<Document> doucumentQueue = new Queue<Document>();
public void AddDocument(Document doc)
{
lock(this)
{
doucumentQueue.Enqueue(doc);
}
}
public Document GetDocument()
{
Document doc = null;
lock (this)
{
doc = doucumentQueue.Dequeue();
}
return doc;
}
public bool IsDocumentAvainable
{
get {
return doucumentQueue.Count > 0;
}
}
}
public class ProcessDocument
{
public static void Start(DocumentManager dm)
{
Task.Factory.StartNew(new ProcessDocument(dm).Run); // Task类表示一个异步操作
}
public ProcessDocument(DocumentManager dm)
{
if (dm == null)
throw new ArgumentException("dm");
documentManager = dm;
}
private DocumentManager documentManager;
protected void Run()
{
while (true)
{
if (documentManager.IsDocumentAvainable)
{
Document doc = documentManager.GetDocument();
Console.WriteLine("Processing Document: {0}", doc.Title);
}
}
Thread.Sleep(new Random().Next(20)); //将线程挂起随机出现的不大于20毫秒的毫秒数。 Thread类创建和控制线程,设置其优先级并获取其状态。
} // Random类表示伪随机数生成器,这是一种能够产生满足某些随机性统计要求的数字序列的设备。
}
}
三、栈
namespace chapter10
{
class Program
{
static void Main()
{
var alphabet = new Stack<char>();
alphabet.Push('A');
alphabet.Push('B');
alphabet.Push('C');
Console.WriteLine("Firsst iteration:");
foreach (var item in alphabet)
{
Console.WriteLine(item);
}
Console.WriteLine("Second iteration:");
while (alphabet.Count > 0)
{
Console.WriteLine(alphabet.Pop()); // peek()获取栈顶元素但不删除元素,contains()确定某个元素是否在栈中,是则返回true;
}
Console.ReadLine();
}
}
}
四、链表(以文档按优先级添加为示例)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
namespace chapter10
{
class Program
{
static void Main()
{
var pdm = new PriorityDocumentmanager();
pdm.AddDocument(new Document("1", "sample", 8));
pdm.AddDocument(new Document("1", "sample", 3));
pdm.AddDocument(new Document("1", "sample", 4));
pdm.AddDocument(new Document("1", "sample", 8));
pdm.AddDocument(new Document("1", "sample", 1));
pdm.AddDocument(new Document("1", "sample", 9));
pdm.AddDocument(new Document("1", "sample", 1));
pdm.AddDocument(new Document("1", "sample", 1));
pdm.DisplayAllNodes();
Console.ReadLine();
}
}
public class Document
{
public string Title { get; private set; }
public string Content { get; private set; }
public byte Priority { get; private set; }
public Document(string title, string content, byte priority)
{
this.Title = title;
this.Content = content;
this.Priority = priority;
}
}
public class PriorityDocumentmanager
{
private readonly LinkedList<Document> documentList; //注意双向链表文档按优先级排列的顺序和优先级节点的取值
private readonly List<LinkedListNode<Document>> priorityNodes;
public PriorityDocumentmanager()
{
documentList = new LinkedList<Document>() ;
priorityNodes = new List<LinkedListNode<Document>>(10);
for (int i = 0; i < 10; i++)
{
priorityNodes.Add(new LinkedListNode<Document>(null));
}
}
public void AddDocument(Document d)
{
if (d == null) throw new ArgumentNullException("d");
AddDocumentToPriorityNode(d, d.Priority);
}
private void AddDocumentToPriorityNode(Document d, int priority)
{
//优先级入口检测
if (priority > 9 || priority < 0)
throw new ArgumentException("Priority must between 0 and 9!");
//是否存在与文档优先级相同的节点
if (priorityNodes[priority].Value == null)
{
--priority;
if (priority >= 0)
{
AddDocumentToPriorityNode(d, priority); //递归,直至找到比文档优先级低的文档或者优先级超过优先级超过下限
}
else //优先级超过优先级超过下限
{
documentList.AddLast(d);
priorityNodes[d.Priority] = documentList.Last;
}
return;
}
else //a priority node exists
{
LinkedListNode<Document> prioNode = priorityNodes[priority];
if (d.Priority == priority) //存在与文档优先级相同的节点
{
documentList.AddAfter(prioNode, d);
priorityNodes[d.Priority] = prioNode.Next;
}
else //存在比文档优先级低的节点
{
LinkedListNode<Document> firstPrioNode = prioNode;
//循环,直至找到同等优先级的第一项(因为在链表中各优先级项首尾相连)
while (firstPrioNode.Previous != null && firstPrioNode.Previous.Value.Priority == prioNode.Value.Priority)
{
firstPrioNode = prioNode.Previous;
prioNode = firstPrioNode;
}
documentList.AddBefore(firstPrioNode, d);
priorityNodes[d.Priority] = firstPrioNode.Previous;
}
}
}
public void DisplayAllNodes()
{
foreach (var dc in documentList)
{
Console.WriteLine("Priority: {0}, Title: {1}", dc.Priority, dc.Title);
}
}
//return rhe document with the highest priority and delete it
public Document GetDocument()
{
Document dc = documentList.First.Value;
documentList.RemoveFirst(); // RemoveLast()方法删除链表最后一项
return dc;
}
}
} // 特别注意,链表中,优先级不同的按照优先级排序,优先级相同的按进入链表的时间先后顺序排序,不同且相邻优先级相关项首尾相连
五、有序列表(按照键给元素排序)
namespace chapter10
{
class Programm
{
static void Main()
{
var books = new SortedList<string, string>(); //有序列表 sortedList<TKey, TValue> 键和值可以使用任意类型
books.Add("fdafdsaf", "4234254");
books.Add("rewr", "42323543");
books["fasdrwaer"] = "423543"; //索引把键作为参数
books["hasdewr"] = "7657653";
foreach (KeyValuePair<string, string> s in books) //枚举器的返回类型为KeyValuePair<TKey, TValue>
{
Console.WriteLine("Key: {0}, Value: {0}", s.Key, s.Value); //通过key, value属性来访问
}
foreach (string s in books.Keys) //通过Keys属性来访问键
{
Console.WriteLine(s);
}
foreach (string s in books.Values) //通过Values属性来访问值
{
Console.WriteLine(s);
}
// 访问(也可用索引器直接访问,但如果不存在,会抛出异常)
string s1 = "fasfas";
string s2;
//避免访问异常的方法
if (!books.TryGetValue(s1, out s2)) //尝试获取指定键的值。 如果使用 ContainsKey()方法,所传递的键在值中,返回true。
{
Console.WriteLine("Title: {0} is not founded", s1);
}
Console.ReadLine();
}
}
}
六、字典
using System.Diagnostics.Contracts;
namespace Chapter10
{
class Program
{
public static void Main()
{
var employees = new Dictionary<EmployeeId, Employee>();
var s1 = new EmployeeId("c323");
var s2 = new Employee("fdfd", 42342.00m, s1);
employees.Add(s1, s2);
var s3 =new EmployeeId("F424");
var s4 = new Employee("fsdaf", 5353.00m, s3);
employees[s3] = s4;
while(true)
{
Console.WriteLine("Enter emplyee Id:");
var userInput = Console.ReadLine();
userInput = userInput.ToUpper();
if (userInput == "X") break;
EmployeeId id;
try
{
id = new EmployeeId(userInput);
Employee employee;
if (!employees.TryGetValue(id, out employee))
{
Console.WriteLine("Employee with {0} does not exist!", id);
}
else
Console.WriteLine(employee);
}
catch (EmployeeIdException e)
{
Console.WriteLine(e.Message);
}
}
}
}
public class EmployeeIdException : Exception
{
public EmployeeIdException(string message) : base(message){}
}
public struct EmployeeId: IEquatable<EmployeeId>
{
private readonly char prefix;
private readonly int number;
public EmployeeId(string id)
{
prefix = (id.ToUpper())[0];
int numberLength = id.Length - 1;
try
{
number = int.Parse(id.Substring(1, numberLength));
}
catch (FormatException)
{
throw new EmployeeIdException("Invalid EmployeeId format!");
}
}
public override string ToString()
{
return prefix.ToString() + string.Format("{0, 6:000000}", number);
}
public override int GetHashCode()
{
return (number ^ number << 16) * 0x15051505;
}
public bool Equals(EmployeeId other)
{
if (other == null)
return false;
return (prefix == other.prefix && number == other.number);
}
public override bool Equals(object obj)
{
return Equals((EmployeeId) obj);
}
public static bool operator ==(EmployeeId left, EmployeeId right)
{
return left.Equals(right);
}
public static bool operator !=(EmployeeId left, EmployeeId right)
{
return !(left == right);
}
}
public class Employee
{
private string name;
private decimal salary;
private readonly EmployeeId id;
public Employee(string name, decimal salary, EmployeeId id)
{
this.name = name;
this.salary = salary;
this.id = id;
}
public override string ToString()
{
return string.Format("{0}: {1, -20} {2:C}", id.ToString(), name, salary);
}
}
}
//lookUp类
var lookUpRacers = racers.ToLookup(r => r.Country); //ToLookup()是一个扩展方法,它用于任何实现了枚举接口的类
foreach (var r in lookUpRacers["Francio"])
Console.Write(r);
// 集合
namespace Chapter10
{
class Programm
{
public static void Main()
{
var companyTeams = new HashSet<string>() { "122", "123", "234" };
var traditionalTeams = new HashSet<string> () { "122", "123" };
var privateTeams = new HashSet<string>() { "222", "223", "543", "4234", "534" };
if (companyTeams.Add("432")) //添加项
Console.WriteLine("432 added");
if (!traditionalTeams.Add("123")) //该项已经存在
Console.WriteLine("123 was already in this set");
if (traditionalTeams.IsSubsetOf(companyTeams))// 子集
Console.WriteLine("traditionalTeams Is Subset Of companyTeams");
if (companyTeams.IsSupersetOf(traditionalTeams))//超集
Console.WriteLine("companyTeams Is Superset Of traditionalTeams");
traditionalTeams.Add("543");
if (traditionalTeams.Overlaps(privateTeams)) //交集
Console.WriteLine("At leat one item is the same with the traditionalTeams and privateTeams");
//用unionwith()方法合集
var AllTeams = new SortedSet<string>(companyTeams);
AllTeams.UnionWith(traditionalTeams);
AllTeams.UnionWith(privateTeams);
Console.WriteLine("\nAll teams:");
foreach (var s in AllTeams)
Console.WriteLine(s);
//用exceptWith()方法集中删除Allteams中的所有私有队
AllTeams.ExceptWith(privateTeams);
Console.WriteLine("\nAll teams:");
foreach (var s in AllTeams)
Console.WriteLine(s); //字符串都是按序输出
Console.Read();
}
}
}
//可观察的集合
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Chapter10
{
class program
{
public static void Main()
{
var data = new ObservableCollection<string>();
data.CollectionChanged += Data_CollectionChanged; //为事件注册方法
data.Add("One");
data.Add("two");
data.Insert(1, "Three");
data.Remove("Three");
Console.Read();
void Data_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Console.WriteLine("Action: {0}", e.Action.ToString()); //获取该事件的操作
if (e.OldItems != null)
{
Console.WriteLine("Starting index for old items: {0}", e.OldStartingIndex);
Console.WriteLine("Ole item(s): ");
foreach (var item in e.OldItems)
Console.WriteLine(item);
}
if (e.NewItems != null)
{
Console.WriteLine("Starting index for new items: {0}", e.NewStartingIndex);
Console.WriteLine("New item(s): ");
foreach (var item in e.NewItems)
Console.WriteLine(item);
}
Console.WriteLine();
}
}
}
}
tips:
1.可以通过索引访问的集合类:ArrayList、StringCollection、List<T>