C# Collections & Generics C#.NET Software Development Version 1.0
Overview Why Collections? Why Generic Datatypes? Collections C# 1.0 Style (object) Collections C# 2.0 Style (Generic) Collections C# 3.0 Initializers Copyright by Dennis A. Fairclough all rights reserved. 2
3 Collections System.Collections Contain object references box and unbox value types as required Arrays, Linked Lists, Trees, Maps, etc. System.Collections.Generic Contain appropriate data types Reduces problems with up/down casting Reduces boxing & unboxing
Generics (C# Standard) 19.1 Generics Generics use classes, structs, methods interfaces, and Delegates (method pointers). to be parameterized by the type of data they store and manipulate. Copyright by Dennis A. Fairclough all rights reserved. 4
Generics C# generics will be immediately familiar to users of generics in Eiffel or Ada, Java or to users of C++ templates, though they do not suffer many of the complications of C++. Copyright by Dennis A. Fairclough all rights reserved. 5
Stack Example (double) public class RStack { private double[] _stack; private int _top; public int Top { get { return _top; } set { _top = value; } } public RStack(int ssize) { _stack = new double[ssize]; _top = 0; } public void Push(double val) { _stack[_top++] = val; } public double Pop() { return _stack[--_top]; } }//END class RStack Copyright by Dennis A. Fairclough all rights reserved. 6
Stack Example (object ref) public class OStack { private object[] _stack; private int _top; public int Top { get { return _top; } set { _top = value; } } public OStack(int ssize) { _stack = new object[ssize]; _top = 0; } public void Push(object val) { _stack[_top++] = val; } public object Pop() { return _stack[--_top]; } }//END class OStack Copyright by Dennis A. Fairclough all rights reserved. 7
Stack Example (generic) unbound type (“class Blueprint”) public class Stack { private T[] _stack; private int _top; public int Top { get { return _top; } set { _top = value; } } public Stack(int ssize) { _stack = new T[ssize]; _top = 0; } public void Push(T val) { _stack[_top++] = val; } public T Pop() { return _stack[--_top]; } }//END class Stack Copyright by Dennis A. Fairclough all rights reserved. 8
Generic Classes In General access_modifier class ident { } Copyright by Dennis A. Fairclough all rights reserved. 9 generic datatype
Generic Methods public void Foo (Stack x,T val) { } Foo (new Stack (5),5.5); Copyright by Dennis A. Fairclough all rights reserved. 10
Copyright by Dennis A. Fairclough all rights reserved. 11 Collection Interfaces IList : ICollection, IEnumerable IList<> ICollection : IEnumerable ICollection<> IDictionary : ICollection, IEnumerable IDictionary<> IEnumerable IEnumerable<> IEnumerator IEnumerator<>
Copyright by Dennis A. Fairclough all rights reserved. 12 IList : ICollection, IEnumerable Add Clear Contains IndexOf Insert Remove RemoveAt Item (indexer) IsFixedSize IsReadOnly
Copyright by Dennis A. Fairclough all rights reserved. 13 ICollection Count (get only) IsSynchronized SyncRoot CopyTo
Copyright by Dennis A. Fairclough all rights reserved. 14 Dictionary : ICollection,IEnumerable Add Clear Contains Remove Item (Indexer) Keys Values IsFixedSize IsReadOnly
Copyright by Dennis A. Fairclough all rights reserved. 15 IEnumerable GetEnumerator Allows use of foreach on a collection
Copyright by Dennis A. Fairclough all rights reserved. 16 IEnumerator Current MoveNext Reset (deprecated)
Copyright by Dennis A. Fairclough all rights reserved. 17 Enumeration (Iterators) Enumeration refers to the process of iterating (stepping) through a collection Enumeration in C# actually implements a modification of the Iterator design pattern It’s called enumeration because as full-blown iteration saved for C# Version 2.0 yield break yield return
Copyright by Dennis A. Fairclough all rights reserved. 18 The Iterator Design Pattern Collection class Nested Iterator class - knows enough about the collection to be able to expose one element of the at a time - Stores its current state Collection class exposes a way to create and initialize one or more iterator(s)
Copyright by Dennis A. Fairclough all rights reserved. 19 Implementing an Enumerator A collection class implements IEnumerable interface Nested Enumerator class implements IEnumerator interface IEnumerable is required if you want to use foreach on your collection Unlike iterators, enumerators have the restriction that, if the collection changes, they become invalid You have to do this in your implementation C# Enumerators also restrict access through the enumerator to read-only NameDescription CurrentGets the current element in the collection. MoveNextAdvances the enumerator to the next element of the collection. ResetSets the enumerator to its initial position, which is before the first element in the collection.
Collections (object ref) Copyright by Dennis A. Fairclough all rights reserved. 20 ClassDescription ArrayListImplements the IList interface using an array whose size is dynamically increased as required.IList BitArrayManages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0). CaseInsensitiveComparerCompares two objects for equivalence, ignoring the case of strings. CaseInsensitiveHashCodeProviderSupplies a hash code for an object, using a hashing algorithm that ignores the case of strings. CollectionBaseProvides the abstract base class for a strongly typed collection. ComparerCompares two objects for equivalence, where string comparisons are case-sensitive. DictionaryBaseProvides the abstract base class for a strongly typed collection of key/value pairs. HashtableRepresents a collection of key/value pairs that are organized based on the hash code of the key. QueueRepresents a first-in, first-out collection of objects. ReadOnlyCollectionBaseProvides the abstract base class for a strongly typed non- generic read-only collection. SortedListRepresents a collection of key/value pairs that are sorted by the keys and are accessible by key and by index. StackRepresents a simple last-in-first-out (LIFO) non-generic collection of objects. Classes
Collections (Generic) Copyright by Dennis A. Fairclough all rights reserved. 21 Description ComparerProvides a base class for implementations of the IComparer generic interface.IComparer DictionaryRepresents a collection of keys and values. Dictionary.KeyCollectionRepresents the collection of keys in a Dictionary. This class cannot be inherited.Dictionary Dictionary.ValueCollectionRepresents the collection of values in a Dictionary. This class cannot be inherited. EqualityComparerProvides a base class for implementations of the IEqualityComparer generic interface.IEqualityComparer KeyNotFoundExceptionThe exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection. LinkedListRepresents a doubly linked list. LinkedListNodeRepresents a node in a LinkedList. This class cannot be inherited.LinkedList ListRepresents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists. QueueRepresents a first-in, first-out collection of objects. SortedDictionaryRepresents a collection of key/value pairs that are sorted on the key. SortedDictionary.KeyCollectionRepresents the collection of keys in a SortedDictionary. This class cannot be inherited.SortedDictionary SortedDictionary.ValueCollectionRepresents the collection of values in a SortedDictionary. This class cannot be inherited SortedListRepresents a collection of key/value pairs that are sorted by key based on the associated IComparer implementation. StackRepresents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type.
Copyright by Dennis A. Fairclough all rights reserved. 22 C# Collections General use: ArrayList and List StringCollection HashTable and Dictionary StringDictionary ListDictionary LinkedList BitArray Hybrids: SortedList SortedDictionary HybridDictionary Specific Use: Queue Stack
Copyright by Dennis A. Fairclough all rights reserved. 23 ArrayList and List Linear array of objects Stored in contiguous memory Implements: IList ICollection IEnumerable ICloneable Resizes Dynamically Index into it like an array Elements must be added before they can be accessed (See ArrayList Demo)
Copyright by Dennis A. Fairclough all rights reserved. 24 Capacity Capacity – Gets or Sets the number of elements the ArrayList/List can contain Count – Gets the number of elements the ArrayList/List actually contains If Count == Capacity and you add 1 or more elements... A new array of twice the size is allocated The old elements are copied into the new location Expensive ! ! ! Set your Capacity upon creation if possible Default capacity is 4 Don’t change it once it is set It will change for you if it needs to
Copyright by Dennis A. Fairclough all rights reserved. 25 Adding elements ArrayList.Add(object obj) Appends the object to the end of the ArrayList ArrayList.AddRange(ICollection c) Appends a collection of objects to the end of the ArrayList ArrayList.Insert(int index, object obj) Inserts the object in the position indicated Has to move (copy) all subsequent elements ArrayList.InsertRange(int index, ICollection c) Inserts the a collection of objects in the position indicated Has to move all subsequent elements
Copyright by Dennis A. Fairclough all rights reserved. 26 Removing Elements ArrayList.Remove(object obj) Removes the first occurrence of obj ArrayList.RemoveAt(int index) Removes the item at the index indicated ArrayList.RemoveRange(int index, int count) Removes count items beginning at index ArrayList.Clear() Removes all the items from the ArrayList Be aware that removing from the middle (or the beginning) of an ArrayList will require moving all subsequent items.
Copyright by Dennis A. Fairclough all rights reserved. 27 Accessing elements Indexer Get and Set an item at the index indicated Returns an object (you must cast) ArrayList.GetRange(int index, int count) Returns a new ArrayList containing the elements from index for count ArrayList.ToArray() Builds a System.Array out of the array list ArrayList.Clone() Makes an exact (shallow) copy of the ArrayList
Collection Initializers & Anonymous Types Collection Initializer List slist = new List {0,1,2,3,4,5}; List clist = new List { new string(“szero”.ToCharArray()), new string(“stwo”.ToCharArray()), new string(“sthree”.ToCharArray()), new string(“sfour”.ToCharArray()), new string(“sfive”.ToCharArray()), } Anonymous Collection Type var temp = new {name="Dennis",number=100}; Copyright by Dennis A. Fairclough all rights reserved. 28
Copyright by Dennis A. Fairclough all rights reserved. 29 foreach on an ArrayList casts automatically Elements are read-only during the foreach ArrayList al = new ArrayList(9); // using Add and AddRange al.Add(0); al.Add(1); al.Add(2); al.Add(3); al.AddRange(new object[] {4, 5, 6, 7, 8}); foreach(int element in al) { Console.Write(element.ToString() + " "); } (Code is from ArrayList Demo)
Copyright by Dennis A. Fairclough all rights reserved. 30 Searching ArrayList.Contains(object item) Indicates whether the array list contains item Performs a linear search ArrayList.IndexOf(object item) Returns the index of the first occurrence of item in the ArrayList Returns -1 if the item is not found ArrayList.IndexOf(object item, int start) Returns the index of the first occurrence of item in the ArrayList after start Use this to search for all occurrences of an object ArrayList.BinarySearch(object item) Requires the ArrayList to be sorted If search fails, BinarySearch returns the inverse of the index of the next-largest item (or if there is no larger element, ArrayList.Count) O ( log (n) )
Copyright by Dennis A. Fairclough all rights reserved. 31 Manipulating Items ArrayList.Reverse() Reverses the elements in the ArrayList ArrayList.Sort() Sorts the ArrayList Requires that all members implement IComparable ArrayList.Sort(IComparer comparer) Sorts the Arraylist Uses the comparer object instead of IComparable interface (if it existed)
Copyright by Dennis A. Fairclough all rights reserved. 32 New in List Stupid name! AsReadOnly ConvertAll FindAll ForEach TrueForAll
Copyright by Dennis A. Fairclough all rights reserved. 33 Specialization: StringCollection StringCollection in System.Collections.Specialized An ArrayList wrapper specialized for strings In 2.0 we can just use List
Copyright by Dennis A. Fairclough all rights reserved. 34 Searching and Sorting Use IComparable and/or IComparer
Copyright by Dennis A. Fairclough all rights reserved. 35 IComparable Required for binary searching and sorting Applies to items inside the Collection An item is said to be “Comparable” to another Comparable items inside a collection can be sorted and searched
Copyright by Dennis A. Fairclough all rights reserved. 36 IComparer Strategy Design Pattern Plug in a new comparer object for different results Can be applied to objects that are not “Comparable” Can be applied to override the comparable functionality that may already exist (See IComparableDemo )
Copyright by Dennis A. Fairclough all rights reserved. 37 Hashtable and Dictionary A collection of Key-Value pairs Actually stored in a DictionaryEntry object Key cannot be null Value can be Implements IDictionary ICollection IEnumerable others
Copyright by Dennis A. Fairclough all rights reserved. 38 Indexing into Hashtables Access into a Hashtable/Dictionary using an indexer: Hashtable ht = new Hashtable(); ht[“hello world”] = new MyObject(); Dictionary dict = new Dictionary (); dict["one"] = new MyObject();
Copyright by Dennis A. Fairclough all rights reserved. 39 How hashing works... GetHashCode() is called on the key Keys are grouped into “buckets” This reduces the number of lookups needed to access Inside a bucket items are stored in a linear array If the maximum ratio of entries-to-buckets (called the load factor) is reached, more buckets are allocated and the entries are redistributed. (Expensive!) You may set the load factor when you create the Hashtable Default is 1.0 (an average of 1 item per bucket) Smaller load factor means faster lookups but take more memory Load factor values can be between.1 and 1.0
Copyright by Dennis A. Fairclough all rights reserved. 40 Indexing into a Hashtable Assignment: If the key does not exist, a new Dictionary entry is created If the key exists, the old value is overwritten Access: If the key does not exist, a KeyNotFoundException is thrown If the key exists, the value item is returned Hashtable ht = new Hashtable(); ht[“hello world”] = new MyObject();
Copyright by Dennis A. Fairclough all rights reserved. 41 Add, Remove, Clear Add(object key, object value) Will add a new DictionaryEntry to the hashtable if key does not already exist If key exists, Add throws an InvalidArgument exception Remove(object key) Removes the corresponding dictionary entry if it exists Clear() Clears all DictionaryEntries from the Hashtable
Copyright by Dennis A. Fairclough all rights reserved. 42 Looking for items Contains(object key) ContiansKey(object key) Both functions act the same Includes Contains to satisfy IDictionary returns true if the Hashtable contains a corresponding DictionaryEntry O( 1 ) ContainsValue(object value) Searches all DictionaryEntries until it finds value or exhausts the Hashtable O ( n )
Copyright by Dennis A. Fairclough all rights reserved. 43 Symbol-Table Hashtable An example from a compiler Symbol-Table lookup: Hashtable table = new Hashtable();... table["if"] = new CToken("if", TokenType.If); table["elseif"] = new CToken("elseif", TokenType.ElseIf); table["else"] = new CToken("else", TokenType.Else); table["endif"] = new CToken("endif", TokenType.EndIf); table["for"] = new CToken("for", TokenType.For); table["foreach"] = new CToken("foreach", TokenType.Foreach); table["in"] = new CToken("in", TokenType.In); public CToken IdentifyNewToken(string lexeme) { if(table.Contains(lexeme)) return (GlobalTable[lexeme] as CToken); else return new CToken(); }
Copyright by Dennis A. Fairclough all rights reserved. 44 foreach on a Hashtable Remember, the Hashtable contains a collection of DictionaryEntry objects That being the case, this won’t work: You can do this: foreach(MyObject mo in _hashtable) { // work here } foreach(DictionaryEntry de in _hashtable) { MyObject mo = (MyObject)de.Value; // work here }
Copyright by Dennis A. Fairclough all rights reserved. 45 foreach on a Hashtable (continued) Or better yet: or: Note: order is not guaranteed foreach(MyObject mo in hashtable.Values) { // work here } foreach(MyObject mo in hashtable.Keys) { // work here }
Copyright by Dennis A. Fairclough all rights reserved. 46 Keys and Values Properties Keys An ICollection of the keys Values An ICollection of the values Order is not specified in either, except that it will be the same between them Items in these ICollections refer to the items in the Hashtable (they are shallow copies)
Copyright by Dennis A. Fairclough all rights reserved. 47 Specialization: StringDictionary StringDictionary in System.Collections.Specialized Adapter Wrapper for a Hashtable exposing strings as the key and value In 2.0 use Dictionary
Copyright by Dennis A. Fairclough all rights reserved. 48 ListDictionary Singly Linked-list key-value collection Faster than Hashtable for small collections (10 Items or less) Add, Remove, Search are all O(n) Implements IDictionary ICollection IEnumerable
Copyright by Dennis A. Fairclough all rights reserved. 49 LinkedList Implements a doubly-linked list (finally!) Uses LinkedListNode Fast insertion/removal Slow indexing (no indexer) Implements: ICollection IEnumerable
Copyright by Dennis A. Fairclough all rights reserved. 50 LinkedList Members Count First Last AddBefore AddAfter AddFirst AddLast Clear Contains Remove RemoveFirst RemoveLast RemoveBefore RemoveAfter
Copyright by Dennis A. Fairclough all rights reserved. 51 BitArray Compact storage for true/false values Stores in 32-bit chunks Bit-wise operations available and, or, not, xor Set(int index, bool value) SetAll(bool value) Use an indexer to access individual items Indexer returns a bool Implements ICollection IEnumerable ICloneable
Copyright by Dennis A. Fairclough all rights reserved. 52 Hybrid: SortedList A cross between a Hashtable and an ArrayList Stores DictionaryEntries in an array sorted by the key Indexing is not as fast as a hashtable Size is adjusted dynamically to meet capacity demands Indexer uses the key: mySortedList[myObject] = valueObject; To access by index, use GetByIndex(int index) and SetByIndex(int index, object value): mySortedList.SetByIndex(0, valueObject) Implements: IDictionary ICollection IEnumerable (See SortedList Demo)
Copyright by Dennis A. Fairclough all rights reserved. 53 Hybrid: HybridDictionary Uses ListDictionary when small, Hashtable when large Moves items when the size increases Implements IDictionary ICollection IEnumerable
Copyright by Dennis A. Fairclough all rights reserved. 54 Queue and Queue Fifo data structure Dynamically resized to fit capacity requirements Implements: ICollection IEnumerable ICloneable
Copyright by Dennis A. Fairclough all rights reserved. 55 Manipulating a Queue Enqueue(object obj) Places obj at the end of the Queue Dequeue() Returns and removes the object at the front of the Queue Throws an InvalidOperationException if the Queue is empty Peek() Returns the object at the front of the Queue Throws an InvalidOperationException if the Queue is empty Clear() Empties the Queue
Copyright by Dennis A. Fairclough all rights reserved. 56 Stack and Stack Lifo data structure Dynamically resizes to meet capacity requirements Implements: ICollection IEnumerable ICloneable
Copyright by Dennis A. Fairclough all rights reserved. 57 Stack Manipulation Push(object obj) Puts obj on the top of the Stack Pop() Returns and removes the item from the top of the Stack Throws an InvalidOperationException if the Stack is empty Peek() Returns the top item from the Stack Throws an InvalidOperationException if the Stack is empty Clear() Clears all elements from the stack
Copyright by Dennis A. Fairclough all rights reserved. 58 CollectionBase Provided as an abstract base class for you to create your own collections Provides the virtual methods: Count Clear() RemoveAt() Provides a place to store your variables: InnerList – is an inherited member (protected) ArrayList
SortedDictionary Demo Code Copyright by Dennis A. Fairclough all rights reserved. 59
Copyright by Dennis A. Fairclough all rights reserved. 60 What did you learn? ??