设为首页 加入收藏

TOP

9.9.9 通用类(4)
2013-10-07 12:44:44 来源: 作者: 【 】 浏览:69
Tags:9.9.9 通用

9.9.9  通用类(4)

for each循环迭代链表中的所有项,并在sum中累计总和。

Count属性返回链表中项的数量,Head和Tail属性返回第一项和最后一项的数值。First和Last属性分别与Head和Tail相同。

5. 存储键/值对的通用词典Dictionary<TKey, TValue>

通用的Dictionary<>集合类要求提供两个类型实参,第一个是键的类型,第二个是与键相关的值的类型。当需要存储的是对象对,而其中一个对象又是访问另一个对象的键时,词典就特别有用。姓名和电话号码是我们希望用词典来存储的键/值对的例子,因为我们通常希望使用姓名作为键来检索电话号码。假设我们已经定义了Name和PhoneNumber类来分别封装姓名和电话号码,那么可以用下面的语句来定义存储姓名/号码对的词典:

  1. Dictionary<Name^, PhoneNumber^>phonebook = gcnew Dictionary<Name^,   
  2. PhoneNumber^>


两个类型实参是Name^和PhoneNumber^,因此键是姓名的句柄,值是电话号码的句柄。

我们可以像下面这样在phonebook词典中添加新的记录项:

  1. Name^ name = gcnew Name("Jim", "Jones");  
  2. PhoneNumber^ number = gcnew PhoneNumber(914, 316, 2233);  
  3. phonebook->Add(name, number);   // Add name/number pair to dictionary 

如果想检索词典中的记录项,则可以使用默认的索引属性。例如:

  1. try  
  2. {  
  3. PhoneNumber^ theNumber = phonebook[name];  
  4. }  
  5. catch(KeyNotFoundFoundException^ knfe)  
  6. {  
  7. Console::WriteLine(knfe);  

我们提供键作为默认索引属性的索引值-- 本例中键是某个Name对象的句柄。如果该键存在,则返回对应的值。如果在集合中没有找到该键,则抛出一个KeyNotFoundException类型的异常。因此,访问键值时只要使用的键有可能不存在,我们就应该将代码放入try代码块内。

Dictionary<>对象有一个Keys属性,该属性返回包含词典中所有键的集合。还有一个Values属性,它返回包含词典中所有值的集合。Count属性返回词典中键/值对的数量。

下面在可运行的示例中实际使用一下通用集合类。

试一试:使用通用集合类

该示例练习使用前面介绍的3个集合类:

  1. // Ex9_22.cpp : main project file.  
  2. // Using generic collection classes  
  3.  
  4. #include "stdafx.h"  
  5.  
  6. using namespace System;  
  7. using namespace System::Collections::Generic; // For generic collections  
  8.  
  9. // Class encapsulating a name  
  10. ref class Name  
  11. {  
  12. public:  
  13. Name(String^ name1, String^ name2) : First(name1),Second(name2){}  
  14. virtual String^ ToString() override{ return First + L" " + Second;}  
  15. private:  
  16. String^ First;  
  17. String^ Second;  
  18. };  
  19.  
  20. // Class encapsulating a phone number  
  21. ref class PhoneNumber  
  22. {  
  23. public:  
  24. PhoneNumber(int area, int local, int number):  
  25. Area(area),Local(local), Number(number){}  
  26. virtual String^ ToString() override  
  27. { return Area + L" " + Local + L" " + Number; }  
  28.  
  29. private:  
  30. int Area;  
  31. int Local;  
  32. int Number;  
  33.  
  34. };  
  35.  
  36. int main(array<System::String ^> ^args)  
  37. {  
  38. // Using List<T> 
  39. Console::WriteLine(L"Creating a List<T> of integers:");  
  40. List<int>numbers = gcnew List<int>;  
  41. for(int i = 0 ; i<1000 ; i++)  
  42. numbers->Add(2*i+1);  
  43.  
  44. // Sum the contents of the list  
  45. int sum = 0;  
  46. for(int i = 0 ; i<numbers->Count ; i++)  
  47. sum += numbers[i];  
  48. Console::WriteLine(L"Total = {0}", sum);  
  49.  
  50. // Using LinkedList<T> 
  51. Console::WriteLine(L"\nCreating a LinkedList<T> of double values:");  
  52. LinkedList<double>values = gcnew LinkedList<double>;  
  53. for(int i = 0 ; i<1000 ; i++)  
  54. values->AddTail(2.5*i);  
  55.  
  56. double sumd = 0.0;  
  57. for each(double v in values)  
  58. sumd += v;  
  59.  
  60. Console::WriteLine(L"Total = {0}", sumd);  
  61.  
  62. LinkedListNode<double>node = values->Find(20.0);  
  63.                                               
    // Find node containing 20.0  
  64. values->AddBefore(node, 19.9);  
  65. values->AddAfter(values->Find(30.0), 30.1);  
  66.  
  67. // Sum the contents of the linked list again  
  68. sumd = 0.0;  
  69. for each(double v in values)  
  70. sumd += v;  
  71.  
  72. Console::WriteLine(L"Total after adding values = {0}", sumd);  
  73.  
  74. // Using Dictionary<K,V> 
  75. Console::WriteLine(L"\nCreating a Dictionary<K,V> of 
    name/number pairs:");  
  76. Dictionary<Name^, PhoneNumber^>phonebook =  
  77.                                   gcnew Dictionary
    <Name^, PhoneNumber^>;  
  78.  
  79. // Add name/number pairs to dictionary  
  80. Name^ name = gcnew Name("Jim", "Jones");  
  81. PhoneNumber^ number = gcnew PhoneNumber(914, 316, 2233);  
  82. phonebook->Add(name, number);  
  83. phonebook->Add(gcnew Name("Fred","Fong"), gcnew PhoneNumber  
  84. (123,234,3456));  
  85. phonebook->Add(gcnew Name("Janet","Smith"), gcnew PhoneNumber  
  86. (515,224,6864));  
  87.  
  88. // List all numbers  
  89. Console::WriteLine(L"List all the numbers:");  
  90. for each(PhoneNumber^ number in phonebook->Values)  
  91. Console::WriteLine(number);  
  92.  
  93. // List names and numbers  
  94. Console::WriteLine(L"Access the keys to list all name/number pairs:");  
  95. for each(Name^ name in phonebook->Keys)  
  96. Console::WriteLine(L"{0} : {1}", name, phonebook[name]);  
  97.  
  98. return 0;  

该示例的输出应该如下所示:

  1. Creating a List<T> of integers:  
  2. Total = 1000000 
  3. Creating a LinkedList<T> of double values:  
  4. Total = 1248750 
  5. Total after adding values = 1248800 
  6.  
  7. Creating a Dictionary<K,V> of name/number pairs:  
  8. List all the numbers:  
  9. 914 316 2233  
  10. 123 234 3456  
  11. 515 224 6864  
  12. Access the keys to list all name/number pairs:  
  13. Jim Jones : 914 316 2233  
  14. Fred Fong : 123 234 3456  
  15. Janet Smith : 515 224 6864 

示例说明

注意指定System::Collections::Generic命名空间的那条using namespace指令。如果希望使用通用集合类时不必指定全限定的类名,那么该using指令就是必需的。

main()中的第一块代码使用了List<>集合,其中的代码与前面相同。该代码块创建了一个在列表中存储整数的类,然后向表中存入1000个数值。求列表内容总和的循环使用了默认的索引属性来检索数值,该循环还可以写成for each循环。不要忘记,默认索引属性只能访问列表中已有的项。我们可以使用默认索引属性修改现有项的值,但不能以这种方式添加新项。我们可以使用Add()函数将新项添加到表尾,也可以使用Insert()函数将新项添加到给定的索引位置。

main()中的下一块代码演示了使用LinkedList<>集合排序double类型数值的方法。我们在for循环中使用AddTail()函数,将double类型的数值添加到链表的尾部。使用AddLast()函数同样能够完成相同的任务。我们在for each循环中检索数值,并求出它们的总和。注意,链表中没有可用于访问表项的默认索引属性。这部分代码还演示了使用Find()、AddBefore()和AddAfter()函数,将新元素添加到链表中特定位置的方法。

main()中的最后一块代码演示了使用Dictionary<>集合,以姓名作为键存储电话号码的方法。Name和Phone number类重写了继承的ToString()函数,从而使Console::WriteLine()函数能够输出适当的这两种类对象的表示方法。有3个姓名/号码对被添加到phonebook词典中。然后使用for each循环,迭代phonebook的Values属性返回的集合对象所包含的所有值,从而输出词典中的所有电话号码。最后一个循环迭代Keys属性返回的集合所包含的所有姓名,并使用phonebook的默认索引属性访问电话号码。这里不需要try代码块,因为我们确信Keys集合中的所有键都在该词典中存在。如果不然,则Dictionary<>通用类的实现肯定存在严重问题!

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇21.1.2 事务 下一篇9.9.9 通用类(3)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: