C#常用容器的使用

C#常用容器的使用

数组

缺点

数组的两个数据间插入数据很麻烦,会有数据搬移操作

声明数组必须指定数组长度

API

Array.IndexOf(arr,”d”) != -1

arr.Length

Array.Clear(arr)

Array.Sort(arr)

Array.Reverse()

ArrayList

优点

不必指定数组的长度,支持动态拓容

缺点

可以存储不同的类型数据,它会把所有元素当作object处理,会有装箱消耗,类型不安全

API

ArrayList list = new ArrayList();

list.Add("abc");//新增

list.Add(123);

list[2] = 35;//修改

list.RemoveAt(0); //移除

list.Insert(0, "qwe");//插入

List,泛型集合

它的大部分用法都与ArrayList相似

关键的区别:声明List集合时,需要为其声明List集合内数据的对象类型

API

List list1 = new List();

list1.Insert(1, wf1); // 在指定位置插入

list1.Remove(wf1);// 删除指定对象的第一个匹配项

list1.Add(new Wife(“aa”)); // 将元素添加到末尾

LinkedList 双链表

结构:LinkedListNode< T >被LinkedList类包含,用LinkedListNode类,可以获得元素的上一个与下一个元素的引用

优点

插入删除快

只需要修改上一个元素的Next与下一个元素的Previous的引用, 像ArrayList列表中,如果插入,需要移动其后的所有元素

缺点

查找慢,链表只能是一个接着一个的访问

与List 对比

List 是数组列表,LinkedList 是双向链表

List读取速度块O(1), 增删O(n),List可以直接通过索引值定位到元素

LinkedList 读取O(n),增删O(1)

API

LinkedList list = new LinkedList();

list.AddFirst(1);

list.AddLast(2);

print(list.Count);

bool have = list.Contains(1);

LinkedListNode first = list.First;

LinkedListNode last = list.Last;

// AddAfter()在某个节点之后添加,AddBefore,Remove() 删除指定的一个匹配对象, RemoveFirst(), RemoveLast()

// Find() 从链表头开始找一个元素,并返回他的节点类,LinkedListNode,FindLast()是从尾部来搜

// Clear() 清除所有元素

HashSet, 表示值的集

与Dictionary几乎一样,差别仅在于HashSet没有key,只有value

表示值的集

不包含任何重复的元素,元素顺序不分先后

用O(n)的空间换取O(1)的查找时间

API

HashSet evenNumbers = new HashSet();

evenNumbers.Add(1);

//UnionWith - Union 或将其设置的添加

//IntersectWith - 交集

//ExceptWith - Set 减法

//SymmetricExceptWith - 余集

HashTable

key/value键值对均为object类型

内部维护很多对Key-Value键值对,其还有一个类似索引的值叫做散列值(HashCode),它是根据GetHashCode方法对Key通过一定算法获取得到的

填充因子:HashTable中的被占用空间达到一个百分比的时候就将该空间自动扩容,扩容的大小是当前空间大小的两倍最接近的素数

缺点,装箱拆箱的消耗,所以就有了Dictionary

对比Dictionary

单线程使用Dictionary, 多线程使用HashTable,HashTable可以通过Hashtable tab = Hashtable.Synchronized(new Hashtable());获得线程安全的对象

```csharp

Hashtable table = new Hashtable();

table.Add(“名字”, “张三”);

print(table[“名字”]);

foreach(DictionEntry entry in table){

print(entry.Key + “:”);

print(entry.Value);

}

```

Dictionary

相对于HashTable,类似于List和ArrayList的关系。它是类型安全的,非线程安全

```csharp

Dictionary dic = new Dictionary();

Person person1 = new Person(){name= “张三”};

dic.Add(“学生1”, person1);

foreach (string key in dic.Keys) //只取key

{

Console.WriteLine(key);

}

foreach (Person person in dic.Values) //只取value

{

Console.WriteLine(person);

}

```

HashSet/HashTable/Dictionary

容器的底层都是Hash表

操作元素

定义int[] m_buckets 数组来保存元素在实际容器Slot[] m_slots 位置

即 Value的保存在 m_slots[m_buckets[value.GetHashCode()%m_buckets.Length]].value

容器长度为质数

质数只能被1和自身整除

减少位置冲突

冲突解决

当位置冲突时使用Slot.next保存数据

数据已满时添加数据

新建一个2倍大小的容器

数据拷贝过去 重新计算位置

Queue

先进先出

Queue q = new Queue();

q.Enque("a");

string str = q.Dequeue();

Stack

后进先出

Stack st = new Stack();

st.Push("a");

string str= st.Pop();

相关内容

14日大嘴世界杯解读:法国憧憬再入决赛,北非黑马稳守反击!
旧版彩票365下载

14日大嘴世界杯解读:法国憧憬再入决赛,北非黑马稳守反击!

⌚ 07-10 👁️‍🗨️ 3030
无尽的祭坛:揭秘DNF无尽祭坛的生存攻略与技巧
旧版彩票365下载

无尽的祭坛:揭秘DNF无尽祭坛的生存攻略与技巧

⌚ 07-25 👁️‍🗨️ 9849

友情链接