原文鏈接: http://blog.csdn.net/shanyongxu/article/details/47071607
Lookup類
Dictionary<Tkey,TValue>只為每個鍵支持一個值.新類Lookup<Tkey,TValue>是.NET3.5中新增的,它類似與Dictionary<Tkey,TElement>,但把鍵映射帶一個值集上.這個類在程序及System.Core中實現,用System,Linq命名空間定義.
Lookup<Tkey,TElement>的方法和屬性如下表:
| 屬性名或者方法名 |
說明 |
| Count |
屬性Count返回集合中的元素個數 |
| Item |
使用索引器可以根據鍵訪問特定的元素.因為同一個鍵可以對應多個值,所以這個屬性返回所有值的枚舉 |
| Contain() |
方法Contains()根據使用用Key參數傳送元素,返回一個布爾值 |
| ApplyResultSelector() |
ApplyResultSelector(0根據傳送給它的轉換函數,轉換每一項,返回一個集合 |
Loopup<TKey,TElement>不能像一般的字典那樣創建,而必須調用方法ToLookup(),它返回一個Lookup<TKey,TElement>對象.方法ToLookup()是一個擴展方法,可以用於實現了IEnumerable<T>的所有類.
當一個Key要求對應多個value情況ToLookup方法非常有用,ToLookup返回一種特殊的數據結構,類似SQL中的group,可以把集合分組並且可以用索引訪問這些元素,案例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lookup類
{
class Program
{
static void Main(string[] args)
{
//創建一個string類型的數組
string[] array = { "cat","dog","horse"};
//生成查找結構
var lookup = array.ToLookup(item => item.Length);
//枚舉字符長度3的串
foreach (var item in lookup[3])
{
Console.WriteLine("3 = "+item);
}
//枚舉字符長度5的串
foreach (var item in lookup[5])
{
Console.WriteLine("5 = " + item);
}
//枚舉分組
foreach (var grouping in lookup)
{
Console.WriteLine("Grouping : ");
foreach (var item in grouping)
{
Console.WriteLine(item);
}
}
Console.ReadKey();
}
}
}
上面的案例是通過數組元素的字符串長度為Key分組,也就是字符長度相同的元素的Key是一樣的,索引下標也是一樣.比如以通過lookup[3]訪問,而horse要用lookup[5]來訪問.
有序字典
SortedDictionary<TKey,TValue>類是一個二叉搜索樹,其中的元素根據鍵來排序.該鍵類型必須實現IComparable<TKey>接口.如果鍵的類型不能排序,則還可以創建一個實現了IComparer<TKey>接口的比較器,將比較器用作有序字典的構造函數的一個參數.
SortedDictionary<TKey,TValue>類和SortedList<TKey,TValue>類的功能類似.但因為SortedList<TKey,TValue>實現為一個基於數組的列表,而SortedDictionary<TKey,TValye>類實現為一個字典,所以他們有不同的特征:
1.SortedList<Tkey,TValue>類使用的內存比SortedDictionary<TKey,TValue>類少
2.SortedDictionary<TKey,TValue>類的元素插入和刪除速度比較快
3.在用已排好序的數據填充集合時,若不需要修改容量,SortedList<TKey,TValue>類就比較快.
案例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 有序字典
{
class Program
{
static void Main(string[] args)
{
//SortedList<TKey,TValue>使用的內存少
//SortedDictionary<TKey,TValue>元素插入和刪除速度快
//鍵要實現IComparable<in T>接口
SortedDictionary<EmployeeID, Person> sd = new SortedDictionary<EmployeeID, Person>();
sd.Add(new EmployeeID(3),new Person("中國", "張飛", 40));
sd.Add(new EmployeeID(20), new Person("中國", "關羽", 43));
sd.Add(new EmployeeID(4), new Person("中國", "劉備", 45));
sd.Add(new EmployeeID(5), new Person("中國", "諸葛亮", 24));
sd.Add(new EmployeeID(1), new Person("美國", "豪威爾", 40));
sd.Add(new EmployeeID(0),new Person("美國", "奧巴馬", 40));
sd.Add(new EmployeeID(210), new Person("朝鮮", "金三胖", 40));
sd.Add(new EmployeeID(80), new Person("印度", "印度阿三", 40));
foreach (var item in sd)
{
Console.WriteLine(item.Key.ID+","+item.Value.Name);//鍵,正序排序
}
Console.ReadKey();
}
}
public class EmployeeID : IComparable<EmployeeID>
{
public int ID { get; private set; }
public EmployeeID(int id)
{
this.ID = id;
}
public int CompareTo(EmployeeID other)
{
return ID.CompareTo(other.ID);
}
}
public class Person
{
public string Country { get; private set; }
public string Name { get; private set; }
public int Age { get; private set; }
public Person(string country, string name, int age)
{
this.Country = country;
this.Name = name;
this.Age = age;
}
}
}
注意:SortedList類使用的內存比SortedDictionary類少,但SortedDictionary類在插入和刪除未排序的數據時比較快.
詳細分析SOrtedList和SortedDictionary類的不同,SortedList內部用數組保存,只能算是有序線性表,而SortedSictionary的內部結構是紅黑樹(這是一種數據結構,不懂得自己去百度).
SortedDictionary內部結構是紅黑樹,紅黑樹的平衡二叉樹的一種,SortedList是有序線性表,內部結構是Array,運用了二分查找法提高效率.從兩者查找,插入,刪除操作的時間復雜度來看,都為O(LogN),分辨不出優劣,但內部結構的不同導致了實際操作的性能差異.
SortedList和SortedDictionary性能比較----插入
由於SortedList用數組保存,每次進行插入操作時,首先用二分查找發找到相應的位置,得到位置以后,SortedList會把該位置以后的值依次往后移動一個位置,空出當前位,再把值插入,這個過程用到了Array.Copy方法,而調用該方法是比較損耗性能的,代碼如下:
private void Insert(int index,TKey key,TValue value)
{
...
if(index<this._size)
{
Array.Copy(this.keys.index,this.keys,index+1,this._size-index);
Array.Copy(this.values,index,this.values,index+1,this._size-index);
}
...
}
SortedDictionary在添加操作時,只會根據紅黑樹的特性,旋轉節點,保持平衡,並沒有對Array.Copy的調用.
測試代碼:循環一個int型,容量為100000的隨機數組,分別用SortedList和SortedDictionary添加.
結論:在大量添加操作的情況下,SortedDictionary性能優於DortedList.
SortedList和SortedDictionary性能比較----查詢
兩者的查詢操作中,事件復雜度都為O(LogN),且源碼中也沒有額外的操作造成性能損失.
經過測試得出:兩者在循環10W次的情況下,僅僅相差幾十毫秒,可以看出兩者的查詢操作性能相差不大.
SortedList和SortedDictionary性能比較----刪除
從添加操作的案例可以看出,由於SortedList內部使用數組進行存儲數據,而數組本身的局限性使得SortedList大部分的添加操作都要滴啊用Array.Copy方法,從而導致了性能的損失,這種情況同樣存在於刪除操作中.所以得出了:在大量刪除操作的情況下是,SortedDictionary的性能優於SortedList.
總結:SortedDictionary內部用紅黑樹存儲數據,SortedList用數組存儲數據,兩者的查詢效率差不多,但由於數組本身的限制,在大量添加刪除操作的情況下,SortedDictionary的性能優於SortedList.
