集合 (collection)

35
1 集集 集集 (Collection) (Collection) 鄭鄭鄭 鄭鄭鄭 鄭鄭鄭鄭鄭鄭 鄭鄭鄭鄭鄭鄭 鄭鄭鄭鄭鄭鄭 鄭鄭鄭鄭鄭鄭 / / 鄭鄭鄭鄭鄭鄭鄭 鄭鄭鄭鄭鄭鄭鄭 / / 鄭鄭鄭鄭鄭鄭鄭 鄭鄭鄭 鄭鄭鄭鄭鄭鄭鄭 鄭鄭鄭

Upload: trent

Post on 15-Jan-2016

50 views

Category:

Documents


0 download

DESCRIPTION

集合 (Collection). 鄭士康 國立台灣大學 電機工程學系 / 電信工程研究所 / 資訊網路與多媒體研究所. Collection, Enumerator, Enumerable. List, ArrayList. 動態陣列 , 動態加入與刪除 , 排序 Enumerator. IEnumerable. IEnumerator. IComparer. ICollection. IList. IDictionary. IComparable. IDictionaryEnumerator. System.Collection. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 集合 (Collection)

1

集合集合(Collection)(Collection)

鄭士康鄭士康國立台灣大學國立台灣大學

電機工程學系電機工程學系 //電信工程研究所電信工程研究所 //資訊網路與多媒體研究所資訊網路與多媒體研究所

Page 2: 集合 (Collection)

2

Collection, Enumerator, Collection, Enumerator, EnumerableEnumerable

Page 3: 集合 (Collection)

3

List, ArrayListList, ArrayList• 動態陣列動態陣列 , , 動態加入與刪除動態加入與刪除 , , 排序排序• EnumeratorEnumerator

Page 4: 集合 (Collection)

4

System.CollectionSystem.CollectionIEnumerable IEnumerator

IComparer

ICollection IDictionaryEnumerator

IList IDictionary

IComparable

Page 5: 集合 (Collection)

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);

Page 6: 集合 (Collection)

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);

Page 7: 集合 (Collection)

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();

Page 8: 集合 (Collection)

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());

Page 9: 集合 (Collection)

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(); }}

Page 10: 集合 (Collection)

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);

}} }}

Page 11: 集合 (Collection)

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); }}

Page 12: 集合 (Collection)

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(); }} }}

Page 13: 集合 (Collection)

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");

}} }}}}

Page 14: 集合 (Collection)

14

練習練習• 撰寫類別撰寫類別 SquareSquare ,模擬邊長為整數,模擬邊長為整數 aa 的正的正方形。注意繼承方形。注意繼承 IComparableIComparable 介面,定義介面,定義 CCompareToompareTo 函式,以便比較不同正方形之大函式,以便比較不同正方形之大小。小。

• 撰寫測試程式,建立正方形的撰寫測試程式,建立正方形的 ArrayListArrayList ,,嘗試加入或刪除其中元素,反轉排列,重嘗試加入或刪除其中元素,反轉排列,重新排序,複製新排序,複製 ArrayListArrayList 、以、以 EnumeratorEnumerator取出所有元素取出所有元素,尋找某一元素,尋找某一元素。。

Page 15: 集合 (Collection)

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

Page 16: 集合 (Collection)

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 ()

Page 17: 集合 (Collection)

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 )

Page 18: 集合 (Collection)

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 {{

Page 19: 集合 (Collection)

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" );

Page 20: 集合 (Collection)

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.

Page 21: 集合 (Collection)

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() ); }}

Page 22: 集合 (Collection)

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();

Page 23: 集合 (Collection)

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.

Page 24: 集合 (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.

Page 25: 集合 (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(); }}

Page 26: 集合 (Collection)

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(); }} }}}}

Page 27: 集合 (Collection)

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; }} }}

Page 28: 集合 (Collection)

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); }} }}

Page 29: 集合 (Collection)

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 ); }}

Page 30: 集合 (Collection)

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); }}

Page 31: 集合 (Collection)

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;

Page 32: 集合 (Collection)

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"); }} }}

Page 33: 集合 (Collection)

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"); }} }}

Page 34: 集合 (Collection)

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"); }} }} }}}}

Page 35: 集合 (Collection)

35

練習練習• 繼承繼承 DictionaryBaseDictionaryBase ,製作成績表類別,製作成績表類別 GrGradeTableadeTable ,以學號為,以學號為 keykey ,, 0~1000~100 之整數之整數為為 valuevalue

• 寫測試程式加入、刪除、修改成績,並列寫測試程式加入、刪除、修改成績,並列印結果印結果

• 加上例外處理加上例外處理