350 likes | 492 Views
集合 (Collection). 鄭士康 國立台灣大學 電機工程學系 / 電信工程研究所 / 資訊網路與多媒體研究所. Collection, Enumerator, Enumerable. List, ArrayList. 動態陣列 , 動態加入與刪除 , 排序 Enumerator. IEnumerable. IEnumerator. IComparer. ICollection. IList. IDictionary. IComparable. IDictionaryEnumerator. System.Collection.
E N D
集合(Collection) 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
List, ArrayList • 動態陣列, 動態加入與刪除, 排序 • Enumerator
IEnumerable IEnumerator IComparer ICollection IList IDictionary IComparable IDictionaryEnumerator System.Collection
UsingArrayList.Program (1/9) using System; using System.Collections; namespace UsingArrayList { /* * 示範ArrayList的使用 * 6/4/2007 */ class Program { static void Main(string[] args) { ArrayList al = new ArrayList(); WriteList(al);
UsingArrayList.Program (2/9) Console.WriteLine( "加入ID為~14之ObjectElement物件"); for (int i = 0; i < 15; ++i) { al.Add(new ObjectElement(i)); } WriteList(al); Console.WriteLine( "在位置及分別插入ID為及之ObjectElement物件"); al.Insert(8, new ObjectElement(17)); al.Insert(16, new ObjectElement(20)); WriteList(al); Console.WriteLine("移走位置,10的物件"); al.Remove(al[2]); al.RemoveAt(10); WriteList(al);
UsingArrayList.Program (3/9) Console.WriteLine("反轉排列順序"); al.Reverse(); WriteList(al); Console.WriteLine("重新由小而大排序"); al.Sort(); WriteList(al); Console.WriteLine("複製ArrayList物件"); ArrayList al2 = (ArrayList)al.Clone(); WriteList(al2); Console.WriteLine("利用Enumerator取得物件"); IEnumerator enumerator = al.GetEnumerator(); while (enumerator.MoveNext()){ ObjectElement oe = (ObjectElement) enumerator.Current; Console.Write(oe.accessID + "\t"); } Console.WriteLine();
UsingArrayList.Program (4/9) int idx; ObjectElement oe17 = new ObjectElement(17); Console.WriteLine("搜尋id為17的物件"); if (al.Contains(oe17)) { idx = al.BinarySearch(oe17, new OEComparer()); Console.WriteLine("於位置{0}找到id為17的物件", idx); } else { Console.WriteLine("沒有找到id為17的物件"); } Console.WriteLine("搜尋id為51的物件"); idx = al.BinarySearch(new ObjectElement(51), new OEComparer());
UsingArrayList.Program (5/9) if (idx >= 0) { Console.WriteLine("於位置{0}找到id為51的物件", idx); } else { Console.WriteLine("沒有找到id為51的物件"); } Console.WriteLine(); }
UsingArrayList.Program (6/9) static void WriteList(ArrayList al) { for (int i = 0; i < al.Count; ++i) { ObjectElement oe = (ObjectElement) al[i]; Console.Write(oe.accessID + "\t"); } Console.WriteLine( "容量=" + al.Capacity + "; 物件數=" + al.Count); } }
UsingArrayList.Program (7/9) public class ObjectElement : IComparable { private int id; public ObjectElement(int id){ this.id = id; } public int accessID{ get { return id; } } public int CompareTo(Object obj){ ObjectElement oe = (ObjectElement)obj; return this.id.CompareTo(oe.id); }
UsingArrayList.Program (8/9) public override bool Equals(object obj) { if (obj is ObjectElement) { ObjectElement oe = (ObjectElement)obj; return this.id == oe.id; } else { return false; } } public override int GetHashCode() { return base.GetHashCode() + id.GetHashCode(); } }
UsingArrayList.Program (9/9) public class OEComparer : IComparer{ public int Compare(Object x, Object y) { if (x.GetType() == typeof(ObjectElement) && y.GetType() == typeof(ObjectElement)) { ObjectElement oex = (ObjectElement)x; ObjectElement oey = (ObjectElement)y; return oex.CompareTo(oey); } throw new ArgumentException( "Use non-ObjectElements for comparison"); } } }
練習 • 撰寫類別Square,模擬邊長為整數a的正方形。注意繼承IComparable介面,定義CompareTo函式,以便比較不同正方形之大小。 • 撰寫測試程式,建立正方形的ArrayList,嘗試加入或刪除其中元素,反轉排列,重新排序,複製ArrayList、以Enumerator取出所有元素,尋找某一元素。
介面IDictionary • 屬性 • Object this [ Object key ] { get; set; } • ICollection Keys { get; } • ICollection Values { get; } • 函式方法 • void Add ( Object key, Object value ) • void Clear () • bool Contains ( Object key ) • void Remove ( Object key ) • IDictionaryEnumerator GetEnumerator ()
類別DictionaryBase • 屬性 • public int Count • protected IDictionary Dictionary { get; } • 函式方法(protected) • virtual void OnInsert ( int index, Object value ) • virtual void OnRemove ( int index, Object value ) • protected virtual void OnSet ( int index, Object oldValue, Object newValue ) • protected virtual void OnValidate ( Object value )
UsingDictionaryBase.Program (1/9) using System; using System.Collections; namespace UsingDictionaryBase { /* * 示範類別DictionaryBase的使用 * ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.cht/cpref2/html/T_System_Collections_DictionaryBase.htm * 6/5/2007 */ class Program {
UsingDictionaryBase.Program (2/9) static void Main(string[] args) { // Creates and initializes a new // DictionaryBase. ShortStringDictionary mySSC = new ShortStringDictionary(); // Adds elements to the collection. mySSC.Add( "One", "a" ); mySSC.Add( "Two", "ab" ); mySSC.Add( "Three", "abc" ); mySSC.Add( "Four", "abcd" ); mySSC.Add( "Five", "abcde" );
UsingDictionaryBase.Program (3/9) // Display the contents of the collection // using foreach. This is the preferred method. Console.WriteLine( "Contents of the collection (using foreach):"); PrintKeysAndValues1( mySSC ); // Display the contents of the collection // using the enumerator. Console.WriteLine( "Contents of the collection (using enumerator):"); PrintKeysAndValues2( mySSC ); // Display the contents of the collection // using the Keys property and the Item // property.
UsingDictionaryBase.Program (4/9) Console.WriteLine( “Contents of the collection(using Keys and Item):"); PrintKeysAndValues3( mySSC ); // Tries to add a value that is too long. try { mySSC.Add( "Ten", "abcdefghij" ); } catch ( ArgumentException e ) { Console.WriteLine( e.ToString() ); }
UsingDictionaryBase.Program (5/9) // Tries to add a key that is too long. try { mySSC.Add( "Eleven", "ijk" ); } catch ( ArgumentException e ) { Console.WriteLine( e.ToString() ); } Console.WriteLine(); // Searches the collection with Contains. Console.WriteLine( "Contains \"Three\": {0}", mySSC.Contains( "Three" ) ); Console.WriteLine( "Contains \"Twelve\": {0}", mySSC.Contains( "Twelve" ) ); Console.WriteLine();
UsingDictionaryBase.Program (6/9) // Removes an element from the collection. mySSC.Remove( "Two" ); // Displays the contents of the collection. Console.WriteLine( "After removing \"Two\":" ); PrintKeysAndValues1( mySSC ); } // Uses the foreach statement which hides the // complexity of the enumerator. // NOTE: The foreach statement is the preferred // way of enumerating the contents of a // collection.
UsingDictionaryBase.Program (7/9) public static void PrintKeysAndValues1( ShortStringDictionary myCol ) { foreach ( DictionaryEntry myDE in myCol ) Console.WriteLine( " {0,-5} : {1}", myDE.Key, myDE.Value ); Console.WriteLine(); } // Uses the enumerator. // NOTE: The foreach statement is the preferred // way of enumerating the contents of a // collection.
UsingDictionaryBase.Program (8/9) public static void PrintKeysAndValues2( ShortStringDictionary myCol ) { DictionaryEntry myDE; System.Collections.IEnumerator myEnumerator = myCol.GetEnumerator(); while ( myEnumerator.MoveNext() ) if ( myEnumerator.Current != null ) { myDE = (DictionaryEntry) myEnumerator.Current; Console.WriteLine( " {0,-5} : {1}", myDE.Key, myDE.Value ); } Console.WriteLine(); }
UsingDictionaryBase.Program (9/9) // Uses the Keys property and the Item property. public static void PrintKeysAndValues3( ShortStringDictionary myCol ) { ICollection myKeys = myCol.Keys; foreach ( String k in myKeys ) Console.WriteLine( " {0,-5} : {1}", k, myCol[k] ); Console.WriteLine(); } } }
UsingDictionaryBase.ShortStringDictoionary (1/8) using System; using System.Collections; namespace UsingDictionaryBase { class ShortStringDictionary : DictionaryBase { public String this[String key] { get{ return ((String)Dictionary[key]); } set{ Dictionary[key] = value; } }
UsingDictionaryBase.ShortStringDictoionary (2/8) public ICollection Keys { get{ return (Dictionary.Keys); } } public ICollection Values { get{ return (Dictionary.Values); } }
UsingDictionaryBase.ShortStringDictoionary (3/8) public void Add(String key, String value) { Dictionary.Add(key, value); } public bool Contains(String key) { return (Dictionary.Contains(key)); } public void Remove( String key ) { Dictionary.Remove( key ); }
UsingDictionaryBase.ShortStringDictoionary (4/8) protected override void OnInsert( Object key, Object value ) { CheckKey(key); CheckValue(value); } protected override void OnRemove(Object key, Object value) { CheckKey(key); } protected override void OnSet(Object key, Object oldValue, Object newValue) { CheckKey(key); CheckValue(newValue); }
UsingDictionaryBase.ShortStringDictoionary (5/8) protected override void OnValidate(Object key, Object value) { CheckKey(key); CheckValue(value); } void CheckKey(Object key) { if (key.GetType() != typeof(System.String)) throw new ArgumentException( "key must be of type String.", "key"); else { String strKey = (String)key;
UsingDictionaryBase.ShortStringDictoionary (6/8) protected override void OnRemove(Object key, Object value) { if (key.GetType() != typeof(System.String)) throw new ArgumentException( "key must be of type String.", "key"); else { String strKey = (String)key; if (strKey.Length > 5) throw new ArgumentException( "key must be no more than 5 characters in length.", "key"); } }
UsingDictionaryBase.ShortStringDictoionary (7/8) if (strKey.Length > 5) throw new ArgumentException( "key must be no more than 5 characters in length.", "key"); } }
UsingDictionaryBase.ShortStringDictoionary (8/8) void CheckValue(Object value) { if (value.GetType() != typeof(System.String)) throw new ArgumentException( "value must be of type String.", "value"); else { String strValue = (String)value; if (strValue.Length > 5) throw new ArgumentException( "value must be no more than 5 characters in length.", "value"); } } } }
練習 • 繼承DictionaryBase,製作成績表類別GradeTable,以學號為key,0~100之整數為value • 寫測試程式加入、刪除、修改成績,並列印結果 • 加上例外處理