SortedList 類 [C#]
命名空間: System.Collections
表示鍵/值對的集合,這些鍵和值按鍵排序並可按照鍵和索引訪問。
SortedList 是 Hashtable 和 Array 的混合。當使用 Item 索引器屬性按照元素的鍵訪問元素時,其行為類似於 Hashtable。當使用 GetByIndex 或 SetByIndex 按照元素的索引訪問元素時,其行為類似於 Array。
SortedList 在內部維護兩個數組以將數組存儲到列表中;即,一個數組用於鍵,另一個數組用於相關聯的值。每個元素都是一個可作為 DictionaryEntry 對象進行訪問的鍵/值對。鍵不能為空引用(Visual Basic 中為 Nothing),但值可以。
SortedList 的容量是列表可擁有的元素數。隨着向 SortedList 中添加元素,容量通過重新分配按需自動增加。可通過調用 TrimToSize 或通過顯式設置 Capacity 屬性減少容量。
SortedList 的元素將按照特定的 IComparer 實現(在創建 SortedList 時指定)或按照鍵本身提供的 IComparable 實現並依據鍵來進行排序。不論在哪種情況下,SortedList 都不允許重復鍵。
索引順序基於排序順序。當添加元素時,元素將按正確的排序順序插入 SortedList,同時索引會相應地進行調整。若移除了元素,索引也會相應地進行調整。因此,當在 SortedList 中添加或移除元素時,特定鍵/值對的索引可能會更改。
由於要進行排序,所以在 SortedList 上操作比在 Hashtable 上操作要慢。但是,SortedList 允許通過相關聯鍵或通過索引對值進行訪問,可提供更大的靈活性。
此集合中的索引從零開始。
C# 語言中的 foreach 語句(在 Visual Basic 中為 for each)需要集合中每個元素的類型。由於 SortedList 的每個元素都是一個鍵/值對,因此元素類型既不是鍵的類型,也不是值的類型。而是 DictionaryEntry 類型。
如:
foreach (DictionaryEntry de in list)
{
Console.WriteLine("遍歷");
Console.WriteLine("/t鍵:{0}/t值:{1}", de.Key, de.Value);
}
System.Object
System.Collections.Generic.SortedList<TKey, TValue>
命名空間: System.Collections.Generic
程序集: System(在 System.dll 中)
[SerializableAttribute] [ComVisibleAttribute(false)] public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable
類型參數
- TKey
-
集合中鍵的類型。
- TValue
-
集合中值的類型。
SortedList<TKey, TValue> 類型公開以下成員。
SortedList<TKey, TValue> 泛型類是具有 O(log n) 檢索的鍵/值對數組,其中 n 是字典中元素的數目。 就這一點而言,它與 SortedDictionary<TKey, TValue> 泛型類相似。 這兩個類具有相似的對象模型,並且都具有 O(log n) 的檢索運算復雜度。 這兩個類的區別在於內存的使用以及插入和移除元素的速度:
SortedList<TKey, TValue> 使用的內存比 SortedDictionary<TKey, TValue> 少。
SortedDictionary<TKey, TValue> 可對未排序的數據執行更快的插入和移除操作,它的運算復雜度為 O(log n),而 SortedList<TKey, TValue> 的運算復雜度為 O(n)。
如果使用排序數據一次性填充列表,則 SortedList<TKey, TValue> 比 SortedDictionary<TKey, TValue> 快。
SortedDictionary<TKey, TValue> 類和 SortedList<TKey, TValue> 類之間的另一個區別是:SortedList<TKey, TValue> 支持通過由 Keys 和 Values 屬性返回的集合對鍵和值執行高效的索引檢索。 訪問此屬性時無需重新生成列表,因為列表只是鍵和值的內部數組的包裝。 下面的代碼演示如何使用 Values 屬性從已排序的字符串列表中按索引檢索值:
string v = mySortedList.Values[3];
SortedList<TKey, TValue> 作為鍵/值對的數組來實現,它按鍵排序。 每個元素都可以作為一個 KeyValuePair<TKey, TValue> 對象進行檢索。
只要鍵對象用作 SortedList<TKey, TValue> 中的鍵,它們就必須是永遠不變的。 SortedList<TKey, TValue> 中的每個鍵必須是唯一的。 鍵不能為 null,但如果列表中值的類型 TValue 為引用類型,則值可以。
SortedList<TKey, TValue> 需要比較器實現來排序和執行比較。 默認比較器 Comparer<T>.Default 檢查鍵類型 TKey 是否實現 System.IComparable<T> 以及是否使用該實現(如果可用)。 否則,Comparer<T>.Default 將檢查鍵類型 TKey 是否實現 System.IComparable。 如果鍵類型 TKey 未實現任一接口,則您可以在構造函數重載中指定一個接受 comparer 參數的 System.Collections.Generic.IComparer<T> 實現。
SortedList<TKey, TValue> 的容量是指 SortedList<TKey, TValue> 可以保存的元素數。 當向 SortedList<TKey, TValue> 中添加元素時,將通過重新分配內部數組來根據需要自動增大容量。 可通過調用 TrimExcess 或通過顯式設置 Capacity 屬性減少容量。 減少容量會重新分配內存並復制 SortedList<TKey, TValue> 中的所有元素。
C# 語言中的 foreach 語句(在 C++ 中為 for each,在 Visual Basic 中為 For Each)需要集合中的元素類型。 由於 SortedList<TKey, TValue> 的元素是鍵/值對,因此元素類型既不是鍵的類型,也不是值的類型。 而是 KeyValuePair<TKey, TValue> 類型。 例如:
foreach( KeyValuePair<int, string> kvp in mySortedList ) { Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value); }
foreach 語句是對枚舉數的包裝,它只允許從集合中讀取,不允許寫入集合。
下面的代碼示例使用字符串鍵創建一個空的字符串 SortedList<TKey, TValue>,並使用 Add 方法添加一些元素。 此示例演示了當嘗試添加重復鍵時,Add 方法會引發 ArgumentException。
此示例使用 Item 屬性(C# 中的索引器)檢索值,演示了當請求的鍵不存在時會引發 KeyNotFoundException,以及與鍵關聯的值可以被替換。
此示例演示如果程序必須經常嘗試排序列表中不存在的鍵值,如何將 TryGetValue 方法作為更有效的值檢索方法,以及在調用 Add 方法前,如何使用 ContainsKey 方法測試鍵是否存在。
此示例演示如何在排序列表中枚舉鍵和值,以及如何使用 Keys 屬性和 Values 屬性分別枚舉鍵和值。
最后,此示例演示了 Remove 方法。
1 using System; 2 using System.Collections.Generic; 3 4 public class Example 5 { 6 public static void Main() 7 { 8 // Create a new sorted list of strings, with string 9 // keys. 10 SortedList<string, string> openWith = 11 new SortedList<string, string>(); 12 13 // Add some elements to the list. There are no 14 // duplicate keys, but some of the values are duplicates. 15 openWith.Add("txt", "notepad.exe"); 16 openWith.Add("bmp", "paint.exe"); 17 openWith.Add("dib", "paint.exe"); 18 openWith.Add("rtf", "wordpad.exe"); 19 20 // The Add method throws an exception if the new key is 21 // already in the list. 22 try 23 { 24 openWith.Add("txt", "winword.exe"); 25 } 26 catch (ArgumentException) 27 { 28 Console.WriteLine("An element with Key = \"txt\" already exists."); 29 } 30 31 // The Item property is another name for the indexer, so you 32 // can omit its name when accessing elements. 33 Console.WriteLine("For key = \"rtf\", value = {0}.", 34 openWith["rtf"]); 35 36 // The indexer can be used to change the value associated 37 // with a key. 38 openWith["rtf"] = "winword.exe"; 39 Console.WriteLine("For key = \"rtf\", value = {0}.", 40 openWith["rtf"]); 41 42 // If a key does not exist, setting the indexer for that key 43 // adds a new key/value pair. 44 openWith["doc"] = "winword.exe"; 45 46 // The indexer throws an exception if the requested key is 47 // not in the list. 48 try 49 { 50 Console.WriteLine("For key = \"tif\", value = {0}.", 51 openWith["tif"]); 52 } 53 catch (KeyNotFoundException) 54 { 55 Console.WriteLine("Key = \"tif\" is not found."); 56 } 57 58 // When a program often has to try keys that turn out not to 59 // be in the list, TryGetValue can be a more efficient 60 // way to retrieve values. 61 string value = ""; 62 if (openWith.TryGetValue("tif", out value)) 63 { 64 Console.WriteLine("For key = \"tif\", value = {0}.", value); 65 } 66 else 67 { 68 Console.WriteLine("Key = \"tif\" is not found."); 69 } 70 71 // ContainsKey can be used to test keys before inserting 72 // them. 73 if (!openWith.ContainsKey("ht")) 74 { 75 openWith.Add("ht", "hypertrm.exe"); 76 Console.WriteLine("Value added for key = \"ht\": {0}", 77 openWith["ht"]); 78 } 79 80 // When you use foreach to enumerate list elements, 81 // the elements are retrieved as KeyValuePair objects. 82 Console.WriteLine(); 83 foreach( KeyValuePair<string, string> kvp in openWith ) 84 { 85 Console.WriteLine("Key = {0}, Value = {1}", 86 kvp.Key, kvp.Value); 87 } 88 89 // To get the values alone, use the Values property. 90 IList<string> ilistValues = openWith.Values; 91 92 // The elements of the list are strongly typed with the 93 // type that was specified for the SorteList values. 94 Console.WriteLine(); 95 foreach( string s in ilistValues ) 96 { 97 Console.WriteLine("Value = {0}", s); 98 } 99 100 // The Values property is an efficient way to retrieve 101 // values by index. 102 Console.WriteLine("\nIndexed retrieval using the Values " + 103 "property: Values[2] = {0}", openWith.Values[2]); 104 105 // To get the keys alone, use the Keys property. 106 IList<string> ilistKeys = openWith.Keys; 107 108 // The elements of the list are strongly typed with the 109 // type that was specified for the SortedList keys. 110 Console.WriteLine(); 111 foreach( string s in ilistKeys ) 112 { 113 Console.WriteLine("Key = {0}", s); 114 } 115 116 // The Keys property is an efficient way to retrieve 117 // keys by index. 118 Console.WriteLine("\nIndexed retrieval using the Keys " + 119 "property: Keys[2] = {0}", openWith.Keys[2]); 120 121 // Use the Remove method to remove a key/value pair. 122 Console.WriteLine("\nRemove(\"doc\")"); 123 openWith.Remove("doc"); 124 125 if (!openWith.ContainsKey("doc")) 126 { 127 Console.WriteLine("Key \"doc\" is not found."); 128 } 129 } 130 } 131 // http://www.cnblogs.com/roucheng/ 132 /* This code example produces the following output: 133 134 An element with Key = "txt" already exists. 135 For key = "rtf", value = wordpad.exe. 136 For key = "rtf", value = winword.exe. 137 Key = "tif" is not found. 138 Key = "tif" is not found. 139 Value added for key = "ht": hypertrm.exe 140 141 Key = bmp, Value = paint.exe 142 Key = dib, Value = paint.exe 143 Key = doc, Value = winword.exe 144 Key = ht, Value = hypertrm.exe 145 Key = rtf, Value = winword.exe 146 Key = txt, Value = notepad.exe 147 148 Value = paint.exe 149 Value = paint.exe 150 Value = winword.exe 151 Value = hypertrm.exe 152 Value = winword.exe 153 Value = notepad.exe 154 155 Indexed retrieval using the Values property: Values[2] = winword.exe 156 157 Key = bmp 158 Key = dib 159 Key = doc 160 Key = ht 161 Key = rtf 162 Key = txt 163 164 Indexed retrieval using the Keys property: Keys[2] = doc 165 166 Remove("doc") 167 Key "doc" is not found. 168 */