Download - 集合 (Collection)
1
集合集合(Collection)(Collection)
鄭士康鄭士康國立台灣大學國立台灣大學
電機工程學系電機工程學系 //電信工程研究所電信工程研究所 //資訊網路與多媒體研究所資訊網路與多媒體研究所
2
Collection, Enumerator, Collection, Enumerator, EnumerableEnumerable
3
List, ArrayListList, ArrayList• 動態陣列動態陣列 , , 動態加入與刪除動態加入與刪除 , , 排序排序• EnumeratorEnumerator
4
System.CollectionSystem.CollectionIEnumerable IEnumerator
IComparer
ICollection IDictionaryEnumerator
IList IDictionary
IComparable
5
UsingArrayList.Program (1/UsingArrayList.Program (1/99))
using System;using System;using System.Collections;using System.Collections;namespace UsingArrayListnamespace UsingArrayList{{ /* /* * * 示範示範 ArrayListArrayList的使用的使用 * 6/4/2007* 6/4/2007 */*/ class Programclass Program {{ static void Main(string[] args)static void Main(string[] args) {{ ArrayList al = new ArrayList();ArrayList al = new ArrayList(); WriteList(al);WriteList(al);
6
UsingArrayList.Program (2/UsingArrayList.Program (2/9)9)
Console.WriteLine(Console.WriteLine( ""加入加入 IDID為為 ~14~14之之 ObjectElementObjectElement物件物件 ");");
for (int i = 0; i < 15; ++i)for (int i = 0; i < 15; ++i) {{ al.Add(new ObjectElement(i));al.Add(new ObjectElement(i)); }} WriteList(al);WriteList(al); Console.WriteLine(Console.WriteLine(
""在位置及分別插入在位置及分別插入 IDID為及之為及之 ObjectElementObjectElement物件物件 ");"); al.Insert(8, new ObjectElement(17));al.Insert(8, new ObjectElement(17)); al.Insert(16, new ObjectElement(20));al.Insert(16, new ObjectElement(20)); WriteList(al);WriteList(al); Console.WriteLine("Console.WriteLine("移走位置移走位置 ,10,10的物件的物件 ");"); al.Remove(al[2]);al.Remove(al[2]); al.RemoveAt(10);al.RemoveAt(10); WriteList(al);WriteList(al);
7
UsingArrayList.Program (3/UsingArrayList.Program (3/9)9)Console.WriteLine("Console.WriteLine("反轉排列順序反轉排列順序 ");");
al.Reverse();al.Reverse(); WriteList(al);WriteList(al); Console.WriteLine("Console.WriteLine("重新由小而大排序重新由小而大排序 ");"); al.Sort();al.Sort(); WriteList(al);WriteList(al); Console.WriteLine("Console.WriteLine("複製複製 ArrayListArrayList物件物件 ");"); ArrayList al2 = (ArrayList)al.Clone();ArrayList al2 = (ArrayList)al.Clone(); WriteList(al2);WriteList(al2); Console.WriteLine("Console.WriteLine("利用利用 EnumeratorEnumerator取得物件取得物件 ");"); IEnumerator enumerator = al.GetEnumerator();IEnumerator enumerator = al.GetEnumerator(); while (enumerator.MoveNext()){while (enumerator.MoveNext()){ ObjectElement oe = (ObjectElement) ObjectElement oe = (ObjectElement)
enumerator.Current;enumerator.Current; Console.Write(oe.accessID + "\t");Console.Write(oe.accessID + "\t"); }} Console.WriteLine();Console.WriteLine();
8
UsingArrayList.Program (4/UsingArrayList.Program (4/99))
int idx;int idx; ObjectElement oe17 = new ObjectElement(17);ObjectElement oe17 = new ObjectElement(17); Console.WriteLine("Console.WriteLine("搜尋搜尋 idid為為 1717的物件的物件 ");"); if (al.Contains(oe17))if (al.Contains(oe17)) {{ idx = al.BinarySearch(oe17, idx = al.BinarySearch(oe17,
new OEComparer());new OEComparer()); Console.WriteLine("Console.WriteLine("於位置於位置 {0}{0}找到找到 idid為為 1717的物件的物件 ", ",
idx);idx); }} elseelse {{ Console.WriteLine("Console.WriteLine("沒有找到沒有找到 idid為為 1717的物件的物件 ");"); }} Console.WriteLine("Console.WriteLine("搜尋搜尋 idid為為 5151的物件的物件 ");"); idx = al.BinarySearch(new ObjectElement(51), idx = al.BinarySearch(new ObjectElement(51),
new OEComparer());new OEComparer());
9
UsingArrayList.Program (5/UsingArrayList.Program (5/99))
if (idx >= 0)if (idx >= 0) {{ Console.WriteLine("Console.WriteLine("於位置於位置 {0}{0}找到找到 idid 為為 5151的物的物件件 ", ", idx);idx);
}} elseelse {{ Console.WriteLine("Console.WriteLine("沒有找到沒有找到 idid 為為 5151的物件的物件 ");"); }} Console.WriteLine();Console.WriteLine(); }}
10
UsingArrayList.Program (6/UsingArrayList.Program (6/9)9)
static void WriteList(ArrayList al)static void WriteList(ArrayList al) {{ for (int i = 0; i < al.Count; ++i)for (int i = 0; i < al.Count; ++i) {{ ObjectElement oe = (ObjectElement) al[i];ObjectElement oe = (ObjectElement) al[i]; Console.Write(oe.accessID + "\t");Console.Write(oe.accessID + "\t"); }} Console.WriteLine(Console.WriteLine(
""容量容量 =" + al.Capacity + "; =" + al.Capacity + "; 物件數物件數 =" + =" + al.Count);al.Count);
}} }}
11
UsingArrayList.Program (7/UsingArrayList.Program (7/9)9)
public class ObjectElement : IComparablepublic class ObjectElement : IComparable {{ private int id;private int id; public ObjectElement(int id)public ObjectElement(int id) {{ this.id = id;this.id = id; }} public int accessIDpublic int accessID {{ get { return id; }get { return id; } }} public int CompareTo(Object obj)public int CompareTo(Object obj) {{ ObjectElement oe = (ObjectElement)obj;ObjectElement oe = (ObjectElement)obj; return this.id.CompareTo(oe.id);return this.id.CompareTo(oe.id); }}
12
UsingArrayList.Program (8/UsingArrayList.Program (8/99))
public override bool Equals(object obj)public override bool Equals(object obj) {{ if (obj is ObjectElement)if (obj is ObjectElement) {{ ObjectElement oe = (ObjectElement)obj;ObjectElement oe = (ObjectElement)obj; return this.id == oe.id;return this.id == oe.id; }} elseelse {{ return false;return false; }} }} public override int GetHashCode()public override int GetHashCode() {{ return base.GetHashCode() + id.GetHashCode();return base.GetHashCode() + id.GetHashCode(); }} }}
13
UsingArrayList.Program (9/UsingArrayList.Program (9/99))
public class OEComparer : IComparerpublic class OEComparer : IComparer {{ public int Compare(Object x, Object y)public int Compare(Object x, Object y) {{ if (x.GetType() == typeof(ObjectElement) && if (x.GetType() == typeof(ObjectElement) && y.GetType() == typeof(ObjectElement))y.GetType() == typeof(ObjectElement)) {{ ObjectElement oex = (ObjectElement)x;ObjectElement oex = (ObjectElement)x; ObjectElement oey = (ObjectElement)y;ObjectElement oey = (ObjectElement)y; return oex.CompareTo(oey);return oex.CompareTo(oey); }} throw new ArgumentException(throw new ArgumentException(
"Use non-ObjectElements for "Use non-ObjectElements for comparison");comparison");
}} }}}}
14
練習練習• 撰寫類別撰寫類別 SquareSquare ,模擬邊長為整數,模擬邊長為整數 aa 的正的正方形。注意繼承方形。注意繼承 IComparableIComparable 介面,定義介面,定義 CCompareToompareTo 函式,以便比較不同正方形之大函式,以便比較不同正方形之大小。小。
• 撰寫測試程式,建立正方形的撰寫測試程式,建立正方形的 ArrayListArrayList ,,嘗試加入或刪除其中元素,反轉排列,重嘗試加入或刪除其中元素,反轉排列,重新排序,複製新排序,複製 ArrayListArrayList 、以、以 EnumeratorEnumerator取出所有元素取出所有元素,尋找某一元素,尋找某一元素。。
15
Dictionary, DictionaryEntry,Dictionary, DictionaryEntry,Keys, ValuesKeys, Values
keykey valuevalue
趙大趙大 (02)77777(02)77777777777
錢二錢二 (02)56565(02)56565656656
孫三孫三 (039)3334(039)33344444
李四李四 (04)66678(04)6667899
周五周五 (02)78978(02)78978922922
吳六吳六 (02)74774(02)74774755755
16
介面介面 IDictionaryIDictionary• 屬性屬性
– ObjectObject this [ this [ ObjectObject key ] { get; set; } key ] { get; set; } – ICollectionICollection Keys { get; } Keys { get; } – ICollectionICollection Values { get; } Values { get; }
• 函式方法函式方法– voidvoid Add ( Add ( ObjectObject key, key, ObjectObject value ) value ) – voidvoid Clear () Clear () – boolbool Contains ( Contains ( ObjectObject key ) key ) – voidvoid Remove ( Remove ( ObjectObject key ) key ) – IDictionaryEnumeratorIDictionaryEnumerator GetEnumerator () GetEnumerator ()
17
類別類別 DictionaryBaseDictionaryBase• 屬性屬性
– public int Countpublic int Count– protected protected IDictionaryIDictionary Dictionary { get; } Dictionary { get; }
• 函式方法函式方法 (protected)(protected)– virtual virtual voidvoid OnInsert ( OnInsert ( intint index, index, ObjectObject valu value ) e )
– virtual void OnRemove ( int index, Object valuvirtual void OnRemove ( int index, Object value )e )
– protected virtual void OnSet ( int index, Objeprotected virtual void OnSet ( int index, Object oldValue, Object newValue ) ct oldValue, Object newValue )
– protected virtual void OnValidate ( Object valprotected virtual void OnValidate ( Object value ) ue )
18
UsingDictionaryBase.Program UsingDictionaryBase.Program (1/9)(1/9)
using System;using System;using System.Collections;using System.Collections;namespace UsingDictionaryBasenamespace UsingDictionaryBase{{ /*/* * * 示範類別示範類別 DictionaryBaseDictionaryBase的使用的使用 * *
ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.cms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.cht/cpref2/html/T_System_Collections_DictionaryBaseht/cpref2/html/T_System_Collections_DictionaryBase.htm.htm
* 6/5/2007* 6/5/2007 */*/ class Programclass Program {{
19
UsingDictionaryBase.Program UsingDictionaryBase.Program (2/9)(2/9)
static void Main(string[] args)static void Main(string[] args) {{ // Creates and initializes a new // Creates and initializes a new
// // DictionaryBase.DictionaryBase. ShortStringDictionary mySSC = new ShortStringDictionary mySSC = new
ShortStringDictionary();ShortStringDictionary();
// Adds elements to the collection.// Adds elements to the collection. mySSC.Add( "One", "a" );mySSC.Add( "One", "a" ); mySSC.Add( "Two", "ab" );mySSC.Add( "Two", "ab" ); mySSC.Add( "Three", "abc" );mySSC.Add( "Three", "abc" ); mySSC.Add( "Four", "abcd" );mySSC.Add( "Four", "abcd" ); mySSC.Add( "Five", "abcde" );mySSC.Add( "Five", "abcde" );
20
UsingDictionaryBase.Program UsingDictionaryBase.Program (3/9)(3/9)
// Display the contents of the collection // Display the contents of the collection // // using foreach. This is the preferred method.using foreach. This is the preferred method.
Console.WriteLine( Console.WriteLine( "Contents of the collection (using foreach):");"Contents of the collection (using foreach):");
PrintKeysAndValues1( mySSC );PrintKeysAndValues1( mySSC );
// Display the contents of the collection // Display the contents of the collection // // using the enumerator.using the enumerator.
Console.WriteLine( Console.WriteLine( "Contents of the collection (using enumerator):");"Contents of the collection (using enumerator):");
PrintKeysAndValues2( mySSC );PrintKeysAndValues2( mySSC );
// Display the contents of the collection // Display the contents of the collection // // using the Keys property and the Item using the Keys property and the Item
// // property.property.
21
UsingDictionaryBase.Program UsingDictionaryBase.Program (4/9)(4/9)
Console.WriteLine( Console.WriteLine( ““CContents of the collectionontents of the collection (using Keys and (using Keys and
Item):");Item):"); PrintKeysAndValues3( mySSC );PrintKeysAndValues3( mySSC );
// Tries to add a value that is too long.// Tries to add a value that is too long. try {try { mySSC.Add( "Ten", "abcdefghij" );mySSC.Add( "Ten", "abcdefghij" ); }} catch ( ArgumentException e ) {catch ( ArgumentException e ) { Console.WriteLine( e.ToString() );Console.WriteLine( e.ToString() ); }}
22
UsingDictionaryBase.Program UsingDictionaryBase.Program (5/9)(5/9)
// Tries to add a key that is too long.// Tries to add a key that is too long. try {try { mySSC.Add( "Eleven", "ijk" );mySSC.Add( "Eleven", "ijk" ); }} catch ( ArgumentException e ) {catch ( ArgumentException e ) { Console.WriteLine( e.ToString() );Console.WriteLine( e.ToString() ); }}
Console.WriteLine();Console.WriteLine();
// Searches the collection with Contains.// Searches the collection with Contains. Console.WriteLine( "Contains \"Three\": {0}", Console.WriteLine( "Contains \"Three\": {0}",
mySSC.Contains( "Three" ) );mySSC.Contains( "Three" ) ); Console.WriteLine( "Contains \"Twelve\": {0}", Console.WriteLine( "Contains \"Twelve\": {0}",
mySSC.Contains( "Twelve" ) );mySSC.Contains( "Twelve" ) ); Console.WriteLine();Console.WriteLine();
23
UsingDictionaryBase.Program UsingDictionaryBase.Program (6/9)(6/9)
// Removes an element from the collection.// Removes an element from the collection. mySSC.Remove( "Two" );mySSC.Remove( "Two" );
// Displays the contents of the collection.// Displays the contents of the collection. Console.WriteLine( "After Console.WriteLine( "After
removing \"Two\":" );removing \"Two\":" ); PrintKeysAndValues1( mySSC );PrintKeysAndValues1( mySSC ); }}
// Uses the foreach statement which hides the // Uses the foreach statement which hides the // // complexity of the enumerator.complexity of the enumerator. // NOTE: The foreach statement is the preferred // NOTE: The foreach statement is the preferred
// // way of enumerating the contents of a way of enumerating the contents of a // // collection.collection.
24
UsingDictionaryBase.Program UsingDictionaryBase.Program (7/9)(7/9)
public static void public static void PrintKeysAndValues1( ShortStringDictionary myCol ) PrintKeysAndValues1( ShortStringDictionary myCol )
{ { foreach ( DictionaryEntry myDE in myCol )foreach ( DictionaryEntry myDE in myCol ) Console.WriteLine( " {0,-5} : {1}", Console.WriteLine( " {0,-5} : {1}",
myDE.Key, myDE.Value );myDE.Key, myDE.Value ); Console.WriteLine();Console.WriteLine(); }}
// Uses the enumerator. // Uses the enumerator. // NOTE: The foreach statement is the preferred // NOTE: The foreach statement is the preferred
// // way of enumerating the contents of a way of enumerating the contents of a // // collection.collection.
25
UsingDictionaryBase.Program UsingDictionaryBase.Program (8/9)(8/9)
public static voidpublic static void PrintKeysAndValues2( ShortStringDictionary PrintKeysAndValues2( ShortStringDictionary
myCol ) {myCol ) { DictionaryEntry myDE;DictionaryEntry myDE; System.Collections.IEnumerator myEnumerator = System.Collections.IEnumerator myEnumerator = myCol.GetEnumerator();myCol.GetEnumerator(); while ( myEnumerator.MoveNext() )while ( myEnumerator.MoveNext() ) if ( myEnumerator.Current != null ) {if ( myEnumerator.Current != null ) { myDE = (DictionaryEntry) myDE = (DictionaryEntry)
myEnumerator.Current;myEnumerator.Current; Console.WriteLine( " {0,-5} : {1}", Console.WriteLine( " {0,-5} : {1}",
myDE.Key, myDE.Value );myDE.Key, myDE.Value ); }} Console.WriteLine();Console.WriteLine(); }}
26
UsingDictionaryBase.Program UsingDictionaryBase.Program (9/9)(9/9)
// Uses the Keys property and the Item property.// Uses the Keys property and the Item property. public static voidpublic static void PrintKeysAndValues3( ShortStringDictionary PrintKeysAndValues3( ShortStringDictionary
myCol ) {myCol ) { ICollection myKeys = myCol.Keys;ICollection myKeys = myCol.Keys; foreach ( String k in myKeys )foreach ( String k in myKeys ) Console.WriteLine( " {0,-5} : {1}", k, Console.WriteLine( " {0,-5} : {1}", k,
myCol[k] );myCol[k] ); Console.WriteLine();Console.WriteLine(); }} }}}}
27
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (1/8)ShortStringDictoionary (1/8)
using System;using System;using System.Collections;using System.Collections;
namespace UsingDictionaryBasenamespace UsingDictionaryBase{{ class ShortStringDictionary : DictionaryBaseclass ShortStringDictionary : DictionaryBase {{ public String this[String key]public String this[String key] {{ getget {{ return ((String)Dictionary[key]);return ((String)Dictionary[key]); }} setset {{ Dictionary[key] = value;Dictionary[key] = value; }} }}
28
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (2/8)ShortStringDictoionary (2/8) public ICollection Keyspublic ICollection Keys
{{ getget {{ return (Dictionary.Keys);return (Dictionary.Keys); }} }} public ICollection Valuespublic ICollection Values {{ getget {{ return (Dictionary.Values);return (Dictionary.Values); }} }}
29
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (3/8)ShortStringDictoionary (3/8) public void Add(String key, String value)public void Add(String key, String value)
{{ Dictionary.Add(key, value);Dictionary.Add(key, value); }}
public bool Contains(String key)public bool Contains(String key) {{ return (Dictionary.Contains(key));return (Dictionary.Contains(key)); }}
public void Remove( String key ) {public void Remove( String key ) { Dictionary.Remove( key );Dictionary.Remove( key ); }}
30
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (4/8)ShortStringDictoionary (4/8) protected override void OnInsert( Object key, protected override void OnInsert( Object key, Object value ) {Object value ) {
CheckKey(key);CheckKey(key); CheckValue(value);CheckValue(value); }} protected override void OnRemove(Object key, protected override void OnRemove(Object key,
Object value)Object value) {{ CheckKey(key);CheckKey(key); }} protected override void OnSet(Object key, protected override void OnSet(Object key,
Object oldValue, Object newValue)Object oldValue, Object newValue) {{ CheckKey(key);CheckKey(key); CheckValue(newValue);CheckValue(newValue); }}
31
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (5/8)ShortStringDictoionary (5/8) protected override void OnValidate(Object key, protected override void OnValidate(Object key,
Object value)Object value) {{ CheckKey(key);CheckKey(key); CheckValue(value);CheckValue(value); }}
void CheckKey(Object key)void CheckKey(Object key) {{ if (key.GetType() != typeof(System.String))if (key.GetType() != typeof(System.String)) throw new ArgumentException(throw new ArgumentException( "key must be of type String.", "key");"key must be of type String.", "key"); elseelse {{ String strKey = (String)key;String strKey = (String)key;
32
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (6/8)ShortStringDictoionary (6/8) protected override void OnRemove(Object key, protected override void OnRemove(Object key,
Object value)Object value) {{ if (key.GetType() != typeof(System.String))if (key.GetType() != typeof(System.String)) throw new ArgumentException(throw new ArgumentException(
"key must be of type String.", "key");"key must be of type String.", "key"); elseelse {{ String strKey = (String)key;String strKey = (String)key; if (strKey.Length > 5)if (strKey.Length > 5) throw new ArgumentException(throw new ArgumentException( "key must be no more than 5 characters in length.", "key must be no more than 5 characters in length.",
"key");"key"); }} }}
33
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (7/8)ShortStringDictoionary (7/8) if (strKey.Length > 5)if (strKey.Length > 5)
throw new ArgumentException(throw new ArgumentException( "key must be no more than 5 characters in "key must be no more than 5 characters in
length.", length.", "key");"key"); }} }}
34
UsingDictionaryBase.UsingDictionaryBase.ShortStringDictoionary (8/8)ShortStringDictoionary (8/8) void CheckValue(Object value)void CheckValue(Object value)
{{ if (value.GetType() != typeof(System.String))if (value.GetType() != typeof(System.String)) throw new ArgumentException(throw new ArgumentException( "value must be of type String.", "value");"value must be of type String.", "value"); elseelse {{ String strValue = (String)value;String strValue = (String)value; if (strValue.Length > 5)if (strValue.Length > 5) throw new ArgumentException(throw new ArgumentException("value must be no more than 5 characters in length.", "value must be no more than 5 characters in length.",
"value");"value"); }} }} }}}}
35
練習練習• 繼承繼承 DictionaryBaseDictionaryBase ,製作成績表類別,製作成績表類別 GrGradeTableadeTable ,以學號為,以學號為 keykey ,, 0~1000~100 之整數之整數為為 valuevalue
• 寫測試程式加入、刪除、修改成績,並列寫測試程式加入、刪除、修改成績,並列印結果印結果
• 加上例外處理加上例外處理