C# 您所在的位置:网站首页 集合和泛型集合的区别 C#

C#

2023-09-03 12:26| 来源: 网络整理| 查看: 265

一、区别

 

非泛型集合

泛型集合

ArrayList

List      using System.Collections.Generic;

HashTable

Dictionary

Queue

Queue   using System.Collections.Generic;

Stack

Stack   using System.Collections.Generic;

SortedList

SortedList

 

设计区别:

非泛型-强类型,在编译期间需要进行类型检查,如List标明我们只能往List集合中存储string 字符串类型,一旦添加其它类型则会在编译时就会得到错误的提示。

泛型-弱类型,在声明的时候就已经指定类型,无法在应用程序编译期间得到检查,如Array 对象,你可以往这个对象中添加数字和字符串都没有问题。但在遍历操作时可以会涉及到类型转换,在不同类型转换时有可能会出现类型转换时的异常。

应用区别:

泛型集合声明的时候会加上,非泛型集合不用

 

所有集合都在库using System.Collections.Generic;和using System.Collections;里,我的理解是三个比较常用 的泛型集合在using System.Collections.Generic;里,其他在using System.Collections;里。新建工程时,默认添加using System.Collections.Generic;库,但是没有using System.Collections;库。官方的意思应该是将 泛型list、queue、stack当成基础应用,鼓励使用。

 

二、泛型集合List

定义:

List variantName = new List(num);

T是一个类,当然可以是任何数据类型(int,string,ushort....),也可以是已有或者自定义的类

num可有可无。

使用:

因为List操作元素比较简单,所以常将int[] 、string[]转化为List、List,处理结束后再转回int[] string[]

泛型最常见的用途是泛型集合,我们在创建列表类(列表类=List)时,列表项的数据类型可能是int,string或其它类型,如果对列表类的处理方法相同,就没有必要事先指定数据类型,留待列表类实例化时再指定。相当于把数据类型当成参数,这样可以最大限度地重用代码,保护类型的安全以及提高性能。

 

(1)基础用法

(1)声明 Listmlist = new List(); eg: string[] Arr = {"a","b","c"}; List mlist = new List(Arr); (2)添加一个元素 List.Add(T item)  eg: mlist.Add("d"); (3)添加集合元素 eg: string[] Arr2 ={"f","g"."h"}; mlist.AddRange(Arr2); (4)在index位置添加一个元素 Insert(int index,T item) eg: mlist.Insert(1,"p"); (5)遍历List中元素   foreach(T element in mlist) T的类型与mlist声明时一样      {        Console.WriteLine(element); } eg: foreach(string s in mlist) { Console.WriteLine(s); } (6)删除元素 List.Remove(T item) 删除一个值 eg: mlist.Remove("a"); List.RemoveAt(int index);删除下标为index的元素 eg: mlist.RemoveAt(0); List.RemoveRange(int index,int count); 下标index开始,删除count个元素 eg:mlist.RemoveRange(3,2); (7)判断某个元素是否在该List中 List.Contains(T item) 返回true或false eg: if(mlist.Contains"("g")) Console.WriteLine("g存在列表中"); else mlist.Add("g"); (8)给List里面元素排序 List.Sort() 默认是元素每一个字母按升序 eg: mlist.Sort(); (9)给List里面元素顺序反转 List.Reverse() 可以与List.Sort()配合使用 (10)List清空 List.Clear() eg: mlist.Clear(); (11)获得List中元素数目 List.Count() 返回int值 eg: mlist.count();

(2)进阶用法

(1)List.FindAll方法:检索与指定谓词所定义的条件相匹配的所有元素 class program { static void Main(stirng[] args) { student stu = new student(); stu.Name="arron"; List students= new List(); students.Add(stu); students.Add(new student("candy")); FindName myname = new FindName("arron"); foreach(student s in students.FindAll(new Predicate(myname.IsName))) { Console.WriteLine(s);} } public class student { public string Name{get;set;} public student(){} public override string ToString() { return string.Format("姓名:{0}",Name); } } public class FindName { private string _name; public FindName(string Name) { this._name=Name;} public bool IsName(student s) { return (s.Name==_name)?true:false;} } (2)List.Find方法 搜索与指定谓词所定义的条件相匹配的元素,并返回整个List中的第一个匹配元素   eg: //Predicate是对方法的委托,如果传递给它的对象与委托定义的条件匹配,则该方法返回true,当前List的元素   被逐个传递给Predicate委托,并在List中间前移动,从第一个元素开始,到最后一个元素结束,当找到匹配项   时处理停止   第一种方法 委托给拉姆达表达式:   eg:   string listFind = mlist.Find(name=> { if(name.length>3) return true; return false; }); 第二种方法 委托给一个函数 eg: public bool ListFind(string name) { if (name.Length > 3) { return true; } return false; } 这两种方法的结果是一样的 (3) List.FindLast方法 public T FindLast(Predicate match);确定是否 List 中的每个元素都与指定的谓词所定义的条件相匹配。用法与List.Find相同。 (4) List.TrueForAll方法: 确定是否 List 中的每个元素都与指定的谓词所定义的条件相匹配。 public bool TrueForAll(Predicate match); (5) List.Take(n): 获得前n行 返回值为IEnumetable,T的类型与List的类型一样 E.g.: IEnumerable takeList= mList.Take(5); foreach (string s in takeList) { Console.WriteLine("element in takeList: " + s); } 这时takeList存放的元素就是mList中的前5个 (6) List.Where方法:检索与指定谓词所定义的条件相匹配的所有元素。跟List.FindAll方法类似。 E.g.: IEnumerable whereList = mList.Where(name => { if (name.Length > 3) { return true; } else { return false; } }); foreach (string s in subList) { Console.WriteLine("element in subList: "+s); } 这时subList存储的就是所有长度大于3的元素 (7)List.RemoveAll方法:移除与指定的谓词所定义的条件相匹配的所有元素。 public int RemoveAll(Predicate match); E.g.: mList.RemoveAll(name => { if (name.Length > 3) { return true; } else { return false; } }); foreach (string s in mList) { Console.WriteLine("element in mList: " + s); } 这时mList存储的就是移除长度大于3之后的元素。

(3)着重介绍

T可以是数据类型,也可以是一个类

class program { static void Main(string[] args) { student stu = new student(); stu.Name = "arron"; List students = new List(); students.Add(stu); students.Add(new student("candy")); FindName myname = new FindName("candy"); foreach (student s in students.FindAll(new Predicate(myname.IsName))) { Console.WriteLine(s); Console.ReadKey(); } } public class student { public string Name { get; set; } public student(string name) { Name = name; } public student() { } public override string ToString() { return string.Format("姓名:{0}", Name); } } public class FindName { private string _name; public FindName(string Name) { this._name = Name; } public bool IsName(student s) { return (s.Name == _name) ? true : false; } } } 三、泛型集合Queue,Stack

队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。

队列在数据缓存中用的比较多。

Queue q = new Queue(); //进队 q.Enqueue('A'); q.Enqueue('M'); q.Enqueue('G'); q.Enqueue('W'); //获取元素个数 int num = q.Count; //判断包含 bool cunzai = q.Contains('A'); //复制到一个数组,类型相对应 char[] aa = q.ToArray(); //遍历队中成员 foreach (char c in q) Console.Write(c + " "); //出队,先出A char ch = (char)q.Dequeue(); //如果元素小于容量90%,设置大小为实际元素数目 q.TrimExcess(); // 查看第一个元素 char x = q.Peek(); //清除队列元素 q.Clear();

堆栈(Stack)代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。

堆栈暂时没实际使用过

Stack st = new Stack(); //进队 st.Push('A'); st.Push('M'); st.Push('G'); st.Push('W'); //遍历 foreach (char c in st) { Console.Write(c + " "); }//W G M A //查看第一个 char cc = st.Peek();//W Console.WriteLine("Current stack: "); //出栈 W st.Pop(); st.Clear();

 

四、非泛型集合ArrayList、Queue、Stack ArrayList 与Array的区别:

Array是System库,有很多操作,包括:

Array.Copy(source, sourceStartIndex, destiny, destinyStartIndex, Length); Array.Copy(source, destiny, Length);//默认从头开始复制 反转数据顺序 Array.Reverse(source);

1.Array 的容量是固定的,而 ArrayList 的容量是根据需要自动扩展的。

2.ArrayList 提供添加、插入或移除某一范围元素的方法。在 Array 中,您只能一次获取或设置一个元素的值。

3.使用 Synchronized 方法可以很容易地创建 ArrayList 的同步版本。而 Array 将一直保持它直到用户实现同步为止。

4.ArrayList 提供将只读和固定大小包装返回到集合的方法。而 Array 不提供。

5.Array 提供 ArrayList 所不具有的某些灵活性:

   a.可以设置 Array 的下限,但 ArrayList 的下限始终为零。

   b.Array 可以具有多个维度,而 ArrayList 始终只是一维的。

   c.特定类型(不包括 Object)的 Array 的性能比 ArrayList 好,这是因为 ArrayList 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和取消装箱。

   d.要求一个数组的大多数情况也可以代之以使用 ArrayList。它更易于使用,并且通常具有与 Object 类型的数组类似的性能。

6.Array 位于 System 命名空间中;ArrayList 位于 System.Collections 命名空间中。

 

ArrayList 与List的区别:

 List和ArrayList的相同点:添加元素、删除元素、通过索引访问元素方法相同。   List和ArrayList的不同点: ArrayList可以添加任意类型元素;List对添加的元素具有类型约束; ArratList添加时装箱,读取时拆箱;List不需要装箱,拆箱操作;

 

其实ArrayList与List,stack与stack,Queue与Queue的使用区别,只有定义的时候不同:

ArrayList x_excel = new ArrayList ();

不用加

 

五、其他

 

 

 

Dictionary   泛型集合

Dictionary dicPoints = new Dictionary();

HashTable 非泛型集合

 1:单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.

 2:多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.

 3:Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便.

Hashtable 类和 Dictionary) 泛型类实现 IDictionary 接口

Dictionary) 泛型类还实现 IDictionary) 泛型接口。因此,这些集合中的每个元素都是一个键/值对。

Dictionary) 类与 Hashtable 类的功能相同

对于值类型,特定类型(不包括 Object)的 Dictionary) 的性能优于 Hashtable,这是因为 Hashtable 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和取消装箱操作。

1.HashTable大数据量插入数据时需要花费比Dictionary大的多的时间。

2.for方式遍历HashTable和Dictionary速度最快。

3.在foreach方式遍历时Dictionary遍历速度更快。

 

在单线程的时候使用Dictionary更好一些,多线程的时候使用HashTable更好。

因为HashTable可以通过Hashtable tab = Hashtable.Synchronized(new Hashtable());获得线程安全的对象。

 

SortedList 泛型集合

如果需要排好序的表,可以使用SortedList。这个类按照键给元素排序。

下面的例子创建一个有序表,其中键和值都是string类型。默认的构造函数创建了一个空表,再用Add()方法添加两本书。使用重载的构造函数,可以定义有序表的容量,传送执行了IComparer接口的对象,用于给有序表中得元素排序。

Add()方法的第一个参数是键(书名),第二个参数是值(ISBN号)。除了使用Add()方法之外,还可以使用索引器将元素添加到有序表中。索引器需要把键作为索引参数。如果键已存在,那么Add()方法就抛出一个ArgumentException类型的异常。如果索引器使用相同的键,就用新值替代旧值。

sortedList 非泛型集合

表示键/值对的集合,这些键值对按键排序并可按照键和索引访问。SortedList 在内部维护两个数组以存储列表中的元素;即,一个数组用于键,另一个数组用于相关联的值。每个元素都是一个可作为 DictionaryEntry 对象进行访问的键/值对。键不能为null,但值可以

1、SortedList 允许通过相关联键或通过索引对值进行访问,可提供更大的灵活性。

2、可根据需要自动增大容量。

 

1、SortedList 的容量是 SortedList 可以保存的元素数。SortedList 的默认初始容量为 0。随着元素添加到 SortedList 中,在需要时可以通过重新分配自动增加容量。可通过调用 TrimToSize方法 或通过显式设置 Capacity 属性减少容量。

2、SortedList 中不允许重复键。

3、SortedList的索引顺序基于排序顺序。当添加元素时,元素将按正确的排序顺序插入 SortedList,同时索引会相应地进行调整。当移除元素时,索引也会相应地进行调整。因此,当在 SortedList 中添加或移除元素时,特定键/值对的索引可能会更改。

4.当不向集合中添加新元素,则调用TrimToSize方法可用于最小化集合的内存开销。

5、通过设置 SortedList 中不存在的键值(例如,myCollection["myNonexistentKey"] = myValue),还可以使用 Item 属性添加新元素。但是,如果指定的键已经存在于 SortedList 中,则设置 Item 属性将改写旧值。相比之下,Add 方法不修改现有元素。

键不能为 空引用(在 Visual Basic 中为 Nothing),但值可以。若要区分由于未找到指定键而返回的 空引用(在 Visual Basic 中为 Nothing) 和由于指定键的值为 空引用(在 Visual Basic 中为 Nothing) 而返回的 空引用(在 Visual Basic 中为 Nothing),请使用 Contains 方法或 ContainsKey 方法确定列表中是否存在该键。

 

IComparer


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有