外星人爸爸 發表於 2020-7-12 17:04:00

C#各类集合介绍

<p>集合(Collection)类是专门用于数据存储和检索的类。这些类提供了对栈(stack)、队列(queue)、列表(list)和哈希表(hash table)的支持。大多数集合类实现了相同的接口。</p>
<p>平常在工作中List&lt;T&gt;集合是用的最多的,其次是Array(数组).今天整理一下各类形式的集合,不用就容易忘,必须要记录一下.</p>
<p><strong>Array</strong></p>
<p>Array:在内存上是连续分配的(可定义长度,也可不定义长度),Array中的元素类型要一样。</p>
<p>Array通过坐标(索引)访问,<strong>读取、修改快---增删慢</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712135158002-1877544590.png" alt="" loading="lazy"></p>
<p>如果Array定义了长度,数据项就不能超过Array中的长度范围.</p>
<p><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712134044246-1643949603.png" alt="" loading="lazy"></p>
<p><strong>ArrayList</strong></p>
<p>ArrayList:不定长度的,连续分配的</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">元素没有类型限制 任何元素都当成object处理,如果是值类型会有装箱操作</span>
ArrayList arrayList = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ArrayList();
arrayList.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以放string</span>
arrayList.Add(Enumerable.Range(<span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>).ToArray());<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以放Array</span>
Func&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">int</span>&gt; func = m =&gt; <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
arrayList.Add(func);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以放Delegate</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">移除数据</span>
arrayList.RemoveAt(<span style="color: rgba(128, 0, 128, 1)">0</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过索引坐标移除</span>
arrayList.Remove(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">匹配第一个元素值,满足就移除</span></pre>
</div>
<p><strong>List</strong></p>
<p>List:也是Array,内存上都是连续摆放的;不定长;泛型,保证类型安全,避免装箱拆箱(都是统一的类型)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> list = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;() { <span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">2</span>, <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)"> };
list.Add(</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
list.AddRange(</span><span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt; { <span style="color: rgba(128, 0, 128, 1)">4</span>, <span style="color: rgba(128, 0, 128, 1)">5</span>, <span style="color: rgba(128, 0, 128, 1)">6</span> });<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">批量添加</span>
list.Any();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断是否有数据</span>
list.Clear();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">清除所有数据</span>
list.ForEach((m) =&gt; { });<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">foreach循环,参数=&gt;viod委托</span>
list.Skip(<span style="color: rgba(128, 0, 128, 1)">1</span>).Take(<span style="color: rgba(128, 0, 128, 1)">2</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">取索引为0之后的两条数据
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">... ...</span></pre>
</div>
<p>以上三种都属于Array类型,只要是Array类型都是读取快(可通过索引访问),增删慢.</p>
<p><strong>LinkedList</strong></p>
<p>LinkedList:双向链表 元素不连续分配,每个元素都有记录前后节点。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">在头部和尾部都标识了上一个元素和下一个元素所处位置</span>
LinkedList&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt; list = <span style="color: rgba(0, 0, 255, 1)">new</span> LinkedList&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
list.AddLast(</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
list.AddFirst(</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> isBool = list.Contains(<span style="color: rgba(128, 0, 128, 1)">1</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断链表中是否有1这个元素</span>
<span style="color: rgba(0, 0, 0, 1)">
LinkedListNode</span>&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt; list1 = list.Find(<span style="color: rgba(128, 0, 128, 1)">123</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">找到元素123的这个节点</span>
list.AddBefore(list1, <span style="color: rgba(128, 0, 128, 1)">0</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">前面增加</span>
list.AddAfter(list1, <span style="color: rgba(128, 0, 128, 1)">0</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">后面增加</span>
<span style="color: rgba(0, 0, 0, 1)">
list.Remove(</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
list.Remove(list1);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据节点删除</span>
<span style="color: rgba(0, 0, 0, 1)">list.RemoveFirst();
list.RemoveLast();
list.Clear();</span></pre>
</div>
<p style="margin-top: -40px"><strong><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712142611445-430189990.png" alt="" loading="lazy"></strong></p>
<p style="margin-top: -45px">&nbsp;链表不能通过元素索引访问。找元素只能遍历。增删比较快,增加或删除,只需把这个元素的前后两个元素指向的元素节点改一下。</p>
<p><strong>Queue</strong></p>
<p>Queue 队列,就是链表&nbsp; 先进先出</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用处;放任务延迟执行A不断写入任务,B不断获取任务执行每次拿最近的一个任务</span>
Queue&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt; queue = <span style="color: rgba(0, 0, 255, 1)">new</span> Queue&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
queue.Enqueue(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加数据</span>
queue.Enqueue(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> queue)
{
    Console.WriteLine(item);
}
queue.Dequeue();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取最先进入队列的元素,获得并移除</span>
queue.Peek();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取但不移除</span></pre>
</div>
<p><strong>Stack</strong></p>
<p>Stack:栈 也是链表, 先进后出 先产生的数据最后使用</p>
<div class="cnblogs_code">
<pre>Stack&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt; stack = <span style="color: rgba(0, 0, 255, 1)">new</span> Stack&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
stack.Push(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加数据</span>
stack.Push(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
stack.Pop();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取最后进入队列的元素获得并移除</span>
stack.Peek();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取不移除</span></pre>
</div>
<p>C#中(线程)栈的内存释放也是一样,先实例化的对象最后释放(在栈中声明的变量,最先声明的最后GC)</p>
<p><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712145340078-1649996664.png" alt="" loading="lazy"></p>
<p><strong>&nbsp;数组和链表(LinkedList、Queue、Stack)是他们内存分配的本质而区分的,元素连续分配和不连续分配.</strong></p>
<p><strong>Set类型集合</strong></p>
<p><strong>HashSet</strong></p>
<p>HashSet:hash分布,元素间没关系(不用记录前后节点),动态增加.</p>
<div class="cnblogs_code">
<pre>HashSet&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt; hashSet = <span style="color: rgba(0, 0, 255, 1)">new</span> HashSet&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
hashSet.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加元素</span>
hashSet.Add(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
hashSet.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object3</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
hashSet.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">会自动去重</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> count = hashSet.Count;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获得数量</span>
hashSet.Contains(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);

HashSet</span>&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt; hashSet1 = <span style="color: rgba(0, 0, 255, 1)">new</span> HashSet&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
hashSet1.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
hashSet1.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
hashSet1.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object4</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
hashSet1.SymmetricExceptWith(hashSet);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">补集:不包含hashSet1和hashSet共有的所有元素</span>
hashSet1.UnionWith(hashSet);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">并集:hashSet1和hashSet所有的元素</span>
hashSet1.ExceptWith(hashSet);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">差集:hashSet1有的元素而hashSet没有的元素</span>
hashSet1.IntersectWith(hashSet);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">交集:共同的元素</span>
<span style="color: rgba(0, 0, 0, 1)">hashSet1.ToList();
hashSet1.Clear();</span></pre>
</div>
<p><strong>SortedSet</strong></p>
<p>SortedSet:排序集合&nbsp; 去重+排序.SortedSet也可以做交差并补.</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">IComparer&lt;T&gt;? comparer自定义对象要排序,就用这个指定</span>
SortedSet&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt; sortedSet = <span style="color: rgba(0, 0, 255, 1)">new</span> SortedSet&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
sortedSet.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
sortedSet.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
sortedSet.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">会自动去重</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> count =<span style="color: rgba(0, 0, 0, 1)"> sortedSet.Count;
sortedSet.Contains(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span>);</pre>
</div>
<p><strong>HashTable(key-value)类型集合</strong></p>
<p><strong>Hashtable:拿着key计算一个内存地址,然后放入key-value。长度不定,可以动态增加。放入的都是object类型,所以避免不了装箱拆箱。</strong></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如果不同的key得到相同的内存地址,第二个在前面的地址上+1,由此会形成数组
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查找的时候,如果地址对应的key不对,那就+1查找</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查找个数据一次定位,增删查改都很快
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">数据太多 重复定位,效率就下去了</span>
Hashtable hashtable = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Hashtable();
hashtable.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">key</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">value</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
hashtable[</span><span style="color: rgba(128, 0, 128, 1)">111</span>] = <span style="color: rgba(128, 0, 128, 1)">222</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">KEY,VALUE</span>
<span style="color: rgba(0, 0, 255, 1)">foreach</span> (DictionaryEntry item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> hashtable)
{
   Console.WriteLine(item.Key.ToString());
   Console.WriteLine(item.Value.ToString());
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">线程安全</span>
Hashtable.Synchronized(hashtable);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">只有一个线程写,多个线程读</span></pre>
</div>
<p><strong>Dictionary:相当于泛型版本的HashTable.因为数据基于泛型,减少了装箱拆箱的消耗.</strong></p>
<div class="cnblogs_code">
<pre>Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>&gt; pairs = <span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
pairs.Add(</span><span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
pairs[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> pairs)
{
    Console.WriteLine(item.Key.ToString(), item.Value);
}
pairs.ContainsKey(</span><span style="color: rgba(128, 0, 128, 1)">1</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">是否存在这个key
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">... ...</span></pre>
</div>
<p><strong>SortedDictionary:排序字典,依据key进行排序.因为要排序,所以增删改慢,多了一个排序</strong></p>
<div class="cnblogs_code">
<pre>SortedDictionary&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>&gt; pairs = <span style="color: rgba(0, 0, 255, 1)">new</span> SortedDictionary&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据key依次排序</span>
pairs.Add(<span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
pairs.Add(</span><span style="color: rgba(128, 0, 128, 1)">2</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
pairs.Add(</span><span style="color: rgba(128, 0, 128, 1)">3</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object3</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
pairs.Add(</span><span style="color: rgba(128, 0, 128, 1)">4</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">object4</span><span style="color: rgba(128, 0, 0, 1)">"</span>);</pre>
</div>
<p><strong>SortedList: 也是key,value形式,自动排序.不能重复添加,key重复会报错</strong></p>
<p>IComparer comparer 自定义对象要排序,就用这个指定</p>
<p style="margin-top: -40px"><strong><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712155830723-1432516337.png" alt="" loading="lazy"></strong></p>
<div class="cnblogs_code" style="margin-top: -55px">
<pre>SortedList sortedList = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SortedList();
sortedList.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">2</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> keyList =<span style="color: rgba(0, 0, 0, 1)"> sortedList.GetKeyList();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> valueList =<span style="color: rgba(0, 0, 0, 1)"> sortedList.GetValueList();
sortedList.TrimToSize();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用于最小化集合的内存开销</span>
sortedList.Remove(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">1</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据key值移除</span>
sortedList.RemoveAt(<span style="color: rgba(128, 0, 128, 1)">0</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据索引移除</span>
sortedList.Clear();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">移除所有元素</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"><strong>字典集合线程不安全(非线程安全),这块内存多个线程都可以改</strong>
ConcurrentQueue 线程安全版本的Queue
ConcurrentStack 线程安全版本的Stack
ConcurrentBag (List集合是非线程安全的)ConcurrentBag线程安全版本的对象集合
ConcurrentDictionary 线程安全版本的Dictionary
BlockingCollection 线程安全集合</span></pre>
</div>
<p>ArrayList和List都实现了IList接口,可以通过索引访问元素,像链表这种就不可以通过索引访问元素.</p>
<p><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712160954040-1769628198.png" alt="" loading="lazy"></p>
<p style="margin-top: -20px">但是链表这种集合继承了ICollection类型的接口,因此可获得集合的长度(长度不定的集合都继承了ICollection接口)</p>
<p style="margin-top: -10px"><img src="https://img2020.cnblogs.com/blog/1677460/202007/1677460-20200712161354712-1745627747.png" alt="" loading="lazy"></p>
<div class="cnblogs_code" style="margin-top: -20px">
<pre><span style="color: rgba(0, 0, 0, 1)">IEnumerable\ICollection\IList\IQueryable
接口是标识功能的.不同的接口拆开就是为了接口隔离.实现不同的接口表明这个集合的功能不同.<br><br></span>任何数据集合都实现IEnumerable,IEnumerable为不同的数据结构(各种集合)提供了统一的数据访问方式(foreach)=》迭代器模式</pre>
</div>
<p>&nbsp;the end!</p><br><br>
来源:https://www.cnblogs.com/zhangnever/p/13288854.html
頁: [1]
查看完整版本: C#各类集合介绍