在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
当元素的个数是动态的,就应使用集合类,集合类一般有List<T>,ArrayList、数组、队列、堆栈、链表等。下面来介绍各种集合的使用方法。 9.1 列表 对象类型的集合主要位于System.collections命名空间中;泛型集合主要是在System.collections.Generic命名空间中,当然List <T>肯定也都在给命名空间下,下面来介绍列表的使用 1.列表初始化 List<int> intList = new List<int>() { 1, 2 }; 定义一个int类型的列表。 2.添加一个元素 intList.Add(3);
3.添加多个元素 intList.AddRange(new int[] { 4, 5 }); AddRange方法的参数是一个IEnumerable<T>类型的对象,当然也可以传送一个数组,上面示例即传送数组。 4.访问元素 访问元素和访问数组很类似的,主要是list<T>都提供了一个索引器,也就是继承了ICollection接口,由于已经提供了索引器了,那么我们就可以像访问数组那样访问数据。 int i=intList[0]; 5.遍历数据 一种是可以使用for来循环迭代集合中的每个元素,使用索引器来访问数据,另一种是使用ForEach主要是Ilist<T>同时也继承了接口IEnumerable,该接口主要是用来迭代数据的。 如下面代码:
Console.WriteLine("For Loop");
for (int i = 0; i < intList.Count;i++) { Console.WriteLine(intList[i]); } Console.WriteLine("ForEach Loop"); foreach(int i in intList) { Console.WriteLine(i.ToString()); } 9.2 队列 队列是其元素以先进先出的方式处理集合。先放进在队列的元素会先读取 。队列的例子很多的,我们常见的就是排队,排在前面的先服务,后来的后服务。 队列和列表的主要区别在于队列没有执行IList接口,所有不能用索引器访问队列。只能添加元素,下面给出个例子来:
队列demo
//队列的使用
public class DocumentManager { private readonly Queue<Document> documentQueue = new Queue<Document>();//定义一个只读的队列 public void AddDocument(Document doc) { lock (this) { documentQueue.Enqueue(doc);//队列尾部添加元素 } } public Document GetDocument() { Document doc = null; lock (this) { doc = documentQueue.Dequeue();//队列头部获得元素 } return doc; } public bool IsDocumentAvailable { get { return documentQueue.Count > 0;//判断队列是否有元素 } } } 9.3 栈 栈和队列是非常相似的集合,只是栈是后进先出而已。
栈Demo
Stack<char> alphalist = new Stack<char>();
alphalist.Push('A'); alphalist.Push('B'); foreach(char a in alphalist) { Console.WriteLine(a); } 说明:由上面的例子可以得出,输入A,B,输出结果为B,A,那么可以得出栈是后进先出。 9.4 链表 LinkedList<T>是一个双向链表,其元素指向他的前后的元素。链表的优点是,能够快速插入列表中间的数据。缺点就是查找速度比较慢。 9.5 有序表 SortList<TKey,Tvalue>,这个类按照键值给元素排序
有序表demo
SortedList<string, string> sortList = new SortedList<string, string>();
sortList.Add("1", "demo"); sortList.Add("2", "demo2"); foreach(KeyValuePair<string,string> m in sortList) { Console.WriteLine("{0},{1}", m.Key, m.Value); } 9.6 字典 字典表示一种复杂的数据结构。字典也成为隐射或散列表。字典的特性是能够快速查找值,也可以自由添加和删除元素。并且没有在内存中移动后续元素的性能开销。 用作字典中的键的类型必须重写object类得GetHashCode方法。只要字典类需要确定元素的位置,就要调用GetHashCode方法。该方法返回的Int由字典用于计算放置元素的索引。另外键类型还必须执行IEquality.Equals的方法或重写object的equals方法,主要是防止不同键值对象可能返回相同的散列码,所以字典使用Equals方法来比较键。下面给出个示例:
字典demo
[Serializable]
public struct EmployeeId : IEquatable<EmployeeId> { private readonly char prefix; private readonly int number; public EmployeeId(string id) { if (id == null) throw new ArgumentNullException("id"); prefix = (id.ToUpper())[0]; int numLength = id.Length - 1; number = int.Parse(id.Substring(1, numLength > 6 ? 6 : numLength)); } 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) { return (prefix == other.prefix && number == other.number); } public override bool Equals(object obj) { if (!(obj is EmployeeId)) return false; return Equals((EmployeeId)obj); } public static bool operator ==(EmployeeId emp1, EmployeeId emp2) { return emp1.Equals(emp2); } public static bool operator !=(EmployeeId emp1, EmployeeId emp2) { return !emp1.Equals(emp2); } } [Serializable] public class Employee { private string name; private decimal salary; private readonly EmployeeId id; public Employee(EmployeeId id, string name, decimal salary) { this.id = id; this.name = name; this.salary = salary; } public override string ToString() { return String.Format("{0}: {1, -20} {2:C}", id.ToString(), name, salary); } } class Program { static void Main() { System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); Dictionary<EmployeeId, Employee> employees = new Dictionary<EmployeeId, Employee>(31); EmployeeId idJeff = new EmployeeId("C7102"); Employee jeff = new Employee(idJeff, "Jeff Gordon", 5164580.00m); employees.Add(idJeff, jeff); Console.WriteLine(jeff); EmployeeId idTony = new EmployeeId("C7105"); Employee tony = new Employee(idTony, "Tony Stewart", 4814200.00m); employees.Add(idTony, tony); Console.WriteLine(tony); EmployeeId idDenny = new EmployeeId("C8011"); Employee denny = new Employee(idDenny, "Denny Hamlin", 3718710.00m); employees.Add(idDenny, denny); Console.WriteLine(denny); EmployeeId idCarl = new EmployeeId("F7908"); Employee carl = new Employee(idCarl, "Carl Edwards", 3285710.00m); employees[idCarl] = carl; Console.WriteLine(carl); EmployeeId idMatt = new EmployeeId("F7203"); Employee matt = new Employee(idMatt, "Matt Kenseth", 4520330.00m); employees[idMatt] = matt; Console.WriteLine(matt); while (true) { try { Console.Write("Enter employee id (X to exit)> "); string userInput = Console.ReadLine(); userInput = userInput.ToUpper(); if (userInput == "X") break; EmployeeId id = new EmployeeId(userInput); Employee employee; if (!employees.TryGetValue(id, out employee)) { Console.WriteLine("Employee with id {0} does not exist", id); } else { Console.WriteLine(employee); } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } } } } 9.7 HashSet 这个集合类包含了不重复项的无序列表。能够很方便的插入元素,该类还提供合集和交集。下面给出简单例子:
哈希集合demo
using System;
using System.Collections.Generic; using System.Linq; using System.Text; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { HashSet<string> companyTeams = new HashSet<string>() { "Ferrari", "McLaren", "Toyota", "BMW", "Renault", "Honda" }; HashSet<string> traditionalTeams = new HashSet<string>() { "Ferrari", "McLaren" }; HashSet<string> privateTeams = new HashSet<string>() { "Red Bull", "Toro Rosso", "Spyker", "Super Aguri" }; //添加没有重复,返回true if (privateTeams.Add("Williams")) Console.WriteLine("Williams added"); if (!companyTeams.Add("McLaren")) Console.WriteLine("McLaren was already in this set"); //子集 if (traditionalTeams.IsSubsetOf(companyTeams)) { Console.WriteLine("traditionalTeams is a subset of companyTeams"); } //超集 if (companyTeams.IsSupersetOf(traditionalTeams)) { Console.WriteLine("companyTeams is a superset of traditionalTeams"); } traditionalTeams.Add("Williams"); //至少有一个元素相同 if (privateTeams.Overlaps(traditionalTeams)) { Console.WriteLine("at least one team is the same with the traditional and private teams"); } HashSet<string> allTeams = new HashSet<string>(companyTeams); //添加全部内容到集合中去 allTeams.UnionWith(privateTeams); allTeams.UnionWith(traditionalTeams); Console.WriteLine(); Console.WriteLine("all teams"); foreach (var team in allTeams) { Console.WriteLine(team); } //从集合中删除该集合中所有的元素 allTeams.ExceptWith(privateTeams); Console.WriteLine(); Console.WriteLine("no private team left"); foreach (var team in allTeams) { Console.WriteLine(team); } } } } 9.8 位数组 当我们遇到位运算时候,可以使用BitArray类来处理,该类可以重新设置大小,不需要知道位数,类bitArray是一个引用类型,包含一个int数组,每32位使用一个新的整形。主要提供了,或 、与、异或操作,以及倒置位的值等方法,下面给出例子:
位数组demo
using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.Collections.Specialized; namespace BitArraySample { class Program { static void BitArrayDemo() { BitArray bits1 = new BitArray(8); bits1.SetAll(true); bits1.Set(1, false); bits1[5] = false; bits1[7] = false; Console.Write("initialized: "); DisplayBits(bits1); Console.WriteLine(); DisplayBits(bits1); bits1.Not(); Console.Write(" not "); DisplayBits(bits1); Console.WriteLine(); BitArray bits2 = new BitArray(bits1); bits2[0] = true; bits2[1] = false; bits2[4] = true; DisplayBits(bits1); Console.Write(" or "); DisplayBits(bits2); Console.Write(" : "); bits1.Or(bits2); DisplayBits(bits1); Console.WriteLine(); DisplayBits(bits2); Console.Write(" and "); DisplayBits(bits1); Console.Write(" : "); bits2.And(bits1); DisplayBits(bits2); Console.WriteLine(); DisplayBits(bits1); Console.Write(" xor "); DisplayBits(bits2); bits1.Xor(bits2); Console.Write(" : "); DisplayBits(bits1); Console.WriteLine(); } static void BitVectorDemo() { BitVector32 bits1 = new BitVector32(); int bit1 = BitVector32.CreateMask(); int bit2 = BitVector32.CreateMask(bit1); int bit3 = BitVector32.CreateMask(bit2); int bit4 = BitVector32.CreateMask(bit3); int bit5 = BitVector32.CreateMask(bit4); bits1[bit1] = true; bits1[bit2] = false; bits1[bit3] = true; bits1[bit4] = true; Console.WriteLine(bits1); bits1[0xabcdef] = true; Console.WriteLine(bits1); int received = 0x79abcdef; BitVector32 bits2 = new BitVector32(received); Console.WriteLine(bits2); // sections: FF EEE DDD CCCC BBBBBBBB AAAAAAAAAAAA BitVector32.Section sectionA = BitVector32.CreateSection(0xfff); BitVector32.Section sectionB = BitVector32.CreateSection(0xff, sectionA); BitVector32.Section sectionC = BitVector32.CreateSection(0xf, sectionB); BitVector32.Section sectionD = BitVector32.CreateSection(0x7, sectionC); BitVector32.Section sectionE = BitVector32.CreateSection(0x7, sectionD); BitVector32.Section sectionF = BitVector32.CreateSection(0x3, sectionE); Console.WriteLine("Section A: " + IntToBinaryString(bits2[sectionA], true)); Console.WriteLine("Section B: " + IntToBinaryString(bits2[sectionB], true)); Console.WriteLine("Section C: " + IntToBinaryString(bits2[sectionC], true)); Console.WriteLine("Section D: " + IntToBinaryString(bits2[sectionD], true)); Console.WriteLine("Section E: " + IntToBinaryString(bits2[sectionE], true)); Console.WriteLine("Section F: " + IntToBinaryString(bits2[sectionF], true)); } static string IntToBinaryString(int bits, bool removeTrailingZero) { StringBuilder sb = new StringBuilder(32); for (int i = 0; i < 32; i++) { if ((bits & 0x80000000) != 0) { sb.Append("1"); } else |
请发表评论