C#学习——集合

.net框架为数据存储和检索提供了专门的类,数组即是其中的一类,而集合就是对于数组的增强。

        C# 中,有三种集合类型:

  • 标准
  • 通用的
  • 同时

标准集合继承System.Collections,他们不将元素存储为特定类型的对象,而都是向上转型为 object   类型的对象。        标准集合包括ArrayListHashtableQueueStack

并发集合:C#并发集合是一种特殊的数据结构,它包含可以同时由多个线程访问的元素。它们大多是线程安全的,因此可以放心使用不同的线程来访问它们。此外,它们也可以使用原子操作提供高性能,将运算推迟到另一个线程中,以避免阻塞主线程。当多个线程同时访问并发集合时,必须考虑到会发生读写冲突。例如,当一个线程试图写入数据时,它可能会影响另一个线程正在读取的数据。此外,如果你想保证多线程应用程序的正确性,就可以使用互斥量来锁定集合,这样它就可以避免在同一时间内有多个线程对集合进行访问。.ConcurrentBag<T>、ConcurrentDictionary<TKey,TValue>、ConcurrentQueue<T>和ConcurrentStack<T>等。它们都是在System.Threading.Collections命名空间中定义的。

…………

集合也可以分类为:泛型结合,非泛型集合。

     非泛型集合类位于System.Collections命名空间中;泛型类位于System.Collections.Generic命名空间;分别继承 IEnumerableIEnumerable<T>用来实现轮询功能;实现ICollectionICollection<T>,在此 接口/泛型接口 Count/属性CopyTo/Add/Clear/Remove等方法;继承 IListIList<T>提供了集合的项列表,有IndexOf/Insert/RemoveAt等方法;实现ISet<T>,使集合具有Add()、Remove()、Contains()、Clear()等方法,它还提供了用于迭代集合元素的GetEnumerator()等方法。

                ArrayLIst(非泛型集合) :实现了IListICollectionIEnumerable接口

       Arraylist于普通数组不同的是,其声明时,可以不用指明Arraylist的长度,即动态数组,非泛型集合中的元素都会向上转型为Object 类型。因此会有封箱和拆箱的操作。

        Arraylist 中常用的方法:

Add

将对象添加到 ArrayList 的结尾处。

AddRange

ICollection 的元素添加到 ArrayList 的末尾。

BinarySearch

已重载。 使用对分检索算法在已排序的 ArrayList 或它的一部分中查找特定元素。

Clear

ArrayList 中移除所有元素。

Contains

确定某元素是否在 ArrayList 中。

CopyTo

已重载。 将 ArrayList 或它的一部分复制到一维数组中。

IndexOf

已重载。 返回 ArrayList 或它的一部分中某个值的第一个匹配项的从零开始的索引。

Insert

将元素插入 ArrayList 的指定索引处。 可在任意位置插入。

InsertRange

将集合中的某个元素插入 ArrayList 的指定索引处。

LastIndexOf

已重载。 返回 ArrayList 或它的一部分中某个值的最后一个匹配项的从零开始的索引。

Remove

ArrayList 中移除特定对象的第一个匹配项。

RemoveAt

移除 ArrayList 的指定索引处的元素。

Reverse

已重载。 将 ArrayList 或它的一部分中元素的顺序反转。

Sort

已重载。 对 ArrayList 或它的一部分中的元素进行排序。

ToArray

已重载。 将 ArrayList 的元素复制到新数组中。

例:

 static void Main(string[] args)
        {
            ArrayList array = new ArrayList();
            array.Add(1);
            array.Add("hahaa");
            foreach (var value in array)
            {
                Console.WriteLine("value is {0}", value);
            }
            Console.ReadLine();
        }

        结果:

List:

是可以通过索引访问的对象的强类型列表,  即,仅存放指定类型的数据,不存在转型操作,效率高。  (List<T>实际上是ArrayList的泛型版本)      

        

方法、属性名

说明

Count

用于获取数组中当前元素数量

Item()

通过指定索引获取或设置元素

Add()

List尾部添加一个元素的方法

AddRange()

List尾部添加一组元素

Clear()

List内移除所有元素

Any()

测试一个元素是否在List

Contains()

测试一个元素是否在List

CopyTo()

把一个List拷贝到一维数组内

Exists()

测试一个元素是否在List

Find()

查找并返回List内的出现的第一个匹配元素

FindAll()

查找并返回List内的所有匹配元素

Getrange()

拷贝指定范围的元素到新的List

IndexOf()

查找并返回每一个匹配元素的索引

Insert()

List内插入一个元素

InsertRange()

List内插入一组元素

LastIndexOf()

查找并返回最后一个匹配元素的索引

Remove()

移除与指定元素匹配的第一个元素

RemoveAt()

移除指定索引的元素

RemoveRange()

移除指定范围的元素

Reverse()

反转List内元素的顺序

Sort()

List内的元素进行排序

ToArray()

List内的元素拷贝到一个新的数组内

TrimToSize()

将容量设置为List中元素的实际数目

 static void Main(string[] args)
        {
            List<int> intList = new List<int>();
            Console.WriteLine("intList 的默认容量为:{0}", intList.Count);
            intList.Add(1);
            intList.Add(2);
            intList.Add(3);
            foreach (var value in intList)
            {
                Console.Write("添加元素后list元素"+value + " ");
            }
            Console.WriteLine();
            Console.WriteLine("intList 的当前容量为:{0}", intList.Count );
            Console.ReadLine();
        }

 结果为:

 List<T> 在添加和删除元素等,对 List进行元素的增删,拷贝,都是将原有的元素拷贝到一个新的内存空间。

对于Arraylist 和List<T> 的比较:

        Arraylist 的优点在于可以存放不同数据类型的不定长数据,如果内部初始化数组的长度不足时,会自动扩容2 倍,Arraylist的缺点很明显,因为存储的数据都是object 类型,如果将值类型的数据进行存入取出就要有“装箱拆箱” 的操作,会有性能上的影响。

        

HashSet<T>(泛型集合)

System.Collections.Generic命名空间中包含一个新的集合类:HashSet<T>,包含不重复项的无序列表,它通过使用哈希码来提供更快的查找速度,以及更有效的内存利用。集合基于散列值,插入元素的操作非常快,不需要像List<T>类那样重排集合。它也可以使用差集、交集和并集构建集合

HashSet<T>中常见的方法:

①Add(): 如果元素不在集合中,Add()方法将该元素添加到集合中,返回一个bool值,用于判断元素是否添加成功。

②Clear : 删除集合中的所有元素。

③ Remove()  删除元素中指定元素。

RemoveWhere() : RemoveWhere()方法需要一个Predicate<T>委托作为参数。删除满足谓词条件的所有元素

⑤ ExceptWith():ExceptWith()方法把一个集合作为参数,从集中删除该集合中的所有元素

UnionWith():把传送为参数的集合中的所有元素添加到集中

………………

键值对集合哈希表(Hashtable)

System.Collections命名空间提供的一个容器处理和表现类似key/value的键值对,key通常可用来快速查找,同时key是区分大小写,value用于存储对应于key的值。其中 key/value键值对均为Object类型

        什么情况使用哈希表(HashTable)

(1)某些数据会被高频率查询
(2)数据量大
(3)查询字段包含字符串类型
(4)数据类型不唯一

哈希表的基本使用:

1,需要引用命名空间

using System.Collections;
using System.Collections.Generic;

2,哈希表的基本操作

方法名    描述
Add(key,value)    在哈希表中添加一个key/value键值对
Remove(key)     在哈希表中去除某个key/value键值对
Clear()    从哈希表中移除所有元素
Contains(key)     判断哈希表是否包含特定键key

 Hashtable ht = new Hashtable(); //创建一个hashtable实例
            ht.Add("E", "e");//添加key/键值对  
            ht.Add("A", "a");
            ht.Add("C", "c");
            ht.Add("B", "b");

            string s = (string)ht["A"];
            if (ht.Contains("E")) //判断哈希表是否包含特定键,其返回值为true或false   
                Console.WriteLine("the E key:exist");
            ht.Remove("C");//移除一个key/键值对   
            Console.WriteLine(ht["A"]);//此处输出a   
            ht.Clear();//移除所有元素   
            Console.WriteLine(ht["A"]); //此处将不会有任何输出   
            Console.ReadLine();

3. 哈希表的遍历

 static Hashtable newhashtable = new Hashtable();
        static void Main(string[] args)
        {
            newhashtable.Add("first", "Beijing"); // 添加key /value 键值对
            newhashtable.Add("second", "Shanghai");
            newhashtable.Add("third", "Hangzhou");
            newhashtable.Add("forth", "Nanjing");

            //遍历方法一:遍历哈希表中的键
            foreach (string key in newhashtable.Keys)
            {
                Console.WriteLine(newhashtable[key]);
            }
            Console.WriteLine("--------------------");

            //遍历方法二:遍历哈希表中的值
            foreach (string value in newhashtable.Values)
            {
                Console.WriteLine(value);
            }
            Console.WriteLine("--------------------");

            //遍历方法三:遍历哈希表中的键值
            foreach (DictionaryEntry de in newhashtable)
            {
                Console.WriteLine(de.Value);
            }
            Console.WriteLine("--------------------");

            //遍历方法四:遍历哈希表中的键值
            IDictionaryEnumerator myEnumerator = newhashtable.GetEnumerator();
            while (myEnumerator.MoveNext())
            {
                Console.WriteLine(newhashtable[myEnumerator.Key]);
            }
            Console.ReadLine();

结果:

 DictionaryEntry是C#中的一个数据结构,它允许你将键和值对应在一起。它有两个属性Key和Value。Hashtable 内的每一组对象就是一个DictionaryEntry,在一个Hashtable中,Key的值是不可以重复的,必须是唯一的,但Value的值可以是重复的,在查询时,Key担当索引的功能

Dictionary( TKey , TValue )泛型键值对集合

C# 的 Dictionary<Tkey,TValue> 通过类在内部维护两个数组来实现功能:一个 keys 数组容纳要从其映射的键,另一个 values 容纳映射到的值;在 Dictionary<Tkey,TValue> 集合中插入键 / 值对时,将自动记录哪个键和哪个值关联,从而允许开发人员快速和简单地获取具有指定键的值。

        

        Dictionary<>包含的一些方法:

方法名                                            说明
Add(TKey, TValue)                    将指定的键和值添加到字典中。如果已经存在键,则抛出异
TryAdd(TKey, TValue)                尝试将指定的键和值添加到字典中。如果字典中存在具有给定键的元素,则不会重写元素,也不会做任何操作,返回false,否则返回true。


Clear()                                         将所有键和值从Dictionary中移除。
ContainsKey(TKey)                     确定是否Dictionary包含指定键。
ContainsValue(TValue)               确定是否Dictionary包含指定值。
EnsureCapacity(int)                    确保字典可容纳指定数量的条目,而无需进一步扩展其后备存储器。返回当前Dictionary中的容量。


Remove(Tkey)                            从Dictionary中移除所指定的键的值。
Remove(TKey, TValue)            从Dictionary中删除具有指定键的值,并将删除的键对应的值复制到Value参数。

例:

// Dictionary 用来存储 TKey-TValue 对
Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>();

// 向 Dictionary 中添加指定的 key 和 value 
dict.TryAdd(TKey, TValue);

// 检查指定的 key 是否存在于 Dictionary 中
if (dict.ContainsKey(TKey))
{
    // 如果指定的键存在于 Dictionary 中,则将其删除
    dict.Remove(TKey);
}

        遍历Dictionary<TKey, TValue>

Dictionary<int, string> MyDh = new Dictionary<int, string>(); //实实例化一个Dictionary
            MyDh.Add(1, "111");
            MyDh.Add(2, "222");
            MyDh.Add(3, "333");
            MyDh.Add(4, "444");
            Console.WriteLine("遍历 Key 结果:");
            foreach (int Key in MyDh.Keys)  //遍历Dictionary 的 Key
            {
                Console.WriteLine(Key);
            }
            Console.WriteLine("遍历 Value 结果:");
            foreach (string value in MyDh.Values)       //遍历Dictionary 的 value
            {
                Console.WriteLine(value);
            }
            Console.WriteLine("遍历 Key-Value 结果:");
            foreach (KeyValuePair<int, string> item in MyDh)    //遍历Dictionary 中的 Key-Value
            {
                Console.WriteLine(item.Key + "\t" + item.Value);
            }
            Console.ReadLine();

运行结果:

迭代器(foreach):

        foreach迭代器将对象集合作为参数进行迭代。它从集合中的第一个元素开始,并将每个元素逐一访问并应用指定的操作,直到它检查到最后一个元素。默认取值按照下标升序进行取值。

工作过程:

①.  调用 collectionObject.GetEnumerator () ,返回一个 IEnumerator 对象的引用。这个方法可通过 IEnumerable 接口的实现代码来获得。
②.  调用所返回的 IEnumerator 接口的 MoveNext () 方法。
③.  如果 MoveNext () 方法返回 true ,就使用 IEnumerator 接口的 Current 属性来获取对象的一个引用,用于 foreach 循环。
④.  重复前面两步,直到 MoveNext () 方法返回 false 为止,此时循环停止
定义迭代器的两种情况中:
 ① ——yield 关键字

yield关键字用于返回值为IEnumerable、IEnumerator、IEnumerable<T>、IEnumerator<T>函数中,它有两个使用方法,yield break和yield return。

返回值为IEnumerable、IEnumerator、IEnumerable<T>、IEnumerator<T>的函数会自动生成一个迭代器,每个yield语句都表示一次暂停或中断
yield break用于中断当前迭代,此时,自动生成的迭代器的MoveNext()会返回false。
yield return用于暂停当前函数,并返回一个值,返回的值可以在迭代器中的Current属性中获取。
再次调用迭代器的MoveNext时,会自动从上一个yield return之后开始运行。

例:

 static IEnumerable<int> GetFibonacci() //斐波那契数列生成器
        {
            
            var last = -1;
            var current = 1;
            
           for ( int n= 0;n<15;n++)
            {
                var temp = last;
                last = current;
                current += temp;
                n += 1;
                yield return current; //其返回类型为IEnumerable
            }
            
        }


 static void Main(string[] args)
        {
            
            foreach (var n in GetFibonacci()) //将创建的迭代器,放到foreach中循环
            {
                Console.WriteLine(n);
               
            }
            Console.ReadLine();
        }


 

在一个迭代器方法中,yield可以出现多次,迭代产生的值会按照相应的顺序和执行过程返回,不过,yield return和一般的return不能出现在同一个方法中。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值