windows programming using c# arrays, collections
TRANSCRIPT
Windows Programming Using C#
Arrays, Collections
2
Contents
Arrays Collections Generics Strings
3
Arrays
Arrays are similar to Java int[] intArray;
Creates a reference to an array intArray = new int[5];
Creates an array object and assigns it Array objects are reference types created on the
heap The integers in the array are value types Array indexing is zero based
4
System.Array
All arrays are derived from this class Properties
Length – number of elements in all dimensions
Rank – number of dimensions Methods
BinarySearch – performs a binary search for a member
5
System.Array
Clear – sets a range of elements to 0 or null Clone – creates a shallow copy Copy – copies elements from one array to another getLength – returns the length of a single dimension IndexOf – returns the first occurrence of a value Sort – sorts the array
6
Arrays of Objects
When you create an array of objects, it is simply an array of references to objects, not the actual objects
These references are initialized to null You must then create objects and assign
to each member of the array
7
The foreach Statement
This iterates through all elements of an array or collection foreach (type ident in expression) statement
int[] ar = new int[5] {1,2,3,4,5};foreach(int i in ar) {Console.WriteLine(i);
}
8
Rectangular Arrays
C# supports rectangular and jagged arrays Arrays can be of 1 or more dimensions To declare a rectangular array
int[,] int2d = new int[2,3];for (int i = 0; I < 2; i++) {for(int j = 0; j < 3; j++) {
int2d[i,j] = i+j;}
}
9
Jagged Arrays
These are really arrays of arrays Each member must be created as a separate
array Note the difference in subscripting
int jag[][] = new int[2][];jag[0] = new int[5];jag[1] = new int[10];jag[0][1] = 15;
10
Indexers
Indexers allow any class to be indexed like an array
Indexers are declared in a way similar to properties
They always use the keyword this The index can be an integer or even a string * see IndexedArray
11
Indexers
Create a simple array which can be indexed By an integer By a string using “first”, “middle” or “last”
class IndexedArray { int[] data;
public IndexedArray(int sz) { data = new int[sz]; }…
12
Indexers
An indexer with integer indices
public int this[int index] {
get { return data[index]; }
set { data[index] = value; }
}
13
Indexers An indexer with string indicespublic int this[string index] { get { int idx = 0; switch (index) { case "middle": idx = data.Length / 2; break; case "first": idx = 0; break; case "last": idx = data.Length - 1; break; } return data[idx]; }}
14
Contents
Arrays Collections Generics Strings
15
Collections
Collections are generic data structures for containing objects or primitives
These are often in the form of common data structures like lists, and dictionaries
Many of the collections have interfaces representing their functionality
16
The IEnumerable Interface
This states that the class supports an enumerator or iterator which steps through the elements one-by-one
Classes which implement this interface can be used with the foreach statement
public interface IEnumerable {
IEnumerator GetEnumerator();
}
17
The IEnumerator Interface
This is the interface the enumerator must implement It is usually implemented as a private class within the
class being enumerated
public interface IEnumerator {bool MoveNext();bool Reset();object Current { get; }
}
18
IndexedArrayEnumeratorprivate class IndexedArrayEnumerator: IEnumerator { int idx; IndexedArray theArray;
public IndexedArrayEnumerator(IndexedArray ar) { theArray = ar; idx = -1; }
public bool MoveNext() { idx++; if(idx >= theArray.data.Length) return false; else return true; }
public void Reset() { idx = -1; }
public object Current { get{ return theArray[idx]; } }}
19
Getting an Enumerator
public IEnumerator GetEnumerator()
{
return new IndexedArrayEnumerator(this);
}
This creates and returns an enumerator Using a separate enumerator class allows several
enumerators to operate at the same time
20
The ICollection Interface
Defines properties and methods for all collections
Implements: IEnumerableCount
the number of elements in the collectionCopyTo(Array ar, int idx)
Copies all elements to an array starting at the index
21
ArrayLists
The problem with arrays is their fixed size ArrayLists fix this by resizing the array
when the addition of new members exceeds the capacity
The class has an extensive set of methods
22
ArrayList Methods
Method/Property Description
Capacity The number of elements the list can hold
Item() Indexer
Add() Add an object to the ArrayList
AddRange() Add the elements of a collection to the end of the array
BinarySearch() Binary search
Clear() Removes all elements from the ArrayList
Clone() Creates a shallow copy
Contains() Determines if a value is in the ArrayList
CopyTo() Copies to a 1-D array
23
ArrayList Methods
Method/Property Description
GetEnumerator() Returns an enumerator
GetRange() Copies a range to a new ArrayList
IndexOf() Returns the index of the first occurrence of a value
InsertRange() Inserts elements from a collection
Remove() Removes the first occurrence of an element
RemoveAt() Removes the element as a specific location
Sort() Sorts the ArrayList
ToArray() Copies the elements to a new array
TrimToSize() Sets capacity to current size
24
Sorting
Sorting primitives is easy since comparing one to another is well-defined
Sorting user-defined types is more difficult since you do not know how to compare one to another
There are two solutions IComparable IComparer
25
The IComparable Interface
This require one method CompareTo which returns -1 if the first value is less than the second 0 if the values are equal 1 if the first value is greater than the second
This is a member of the class and compares this to an instance passed as a parameter
public interface IComparable {int CompareTo(object obj)
}
26
The IComparer Interface
This is similar to IComparable but is designed to be implemented in a class outside the class whose instances are being compared
Compare() works just like CompareTo()
public interface IComparer {int Compare(object o1, object o2);
}
27
Sorting an ArrayList
To use CompareTo() of IComparableArrayList.Sort()
To use a custom comparer objectArrayList.Sort(IComparer cmp)
To sort a rangeArrayList.Sort(int start, int len, IComparer cmp)
28
Implementing IComparer
To sort people based on age
class PersonComparer: IComparer{
public int Compare(object o1, object o2){
PersonBase p1 = (PersonBase)o1;PersonBase p2 = (PersonBase)o2;return p1.Age.CompareTo(p2.Age);
}}
29
ICloneable Interface
This guarantees that a class can be cloned The Clone method can be implemented to make
a shallow or deep clone
public interface ICloneable {
object Clone();
}
30
Queue Class
Method Description
Enqueue(object) Adds an object to the queue
object Dequeue() Takes an object off the queue and returns it. Throws InvalidOperationException if empty.
object Peek() Returns object at head of queue without removing it.
object[] ToArray() Returns contents as an array.
• Implements: ICollection, IComparable, ICloneable
31
Stack Class
Method Description
Push(object) Adds an object to the stack
object Pop() Takes an object off the stack and returns it. Throws InvalidOperationException if empty.
object Peek() Returns object at top of stack without removing it.
object[] ToArray() Returns contents as an array.
• Implements: ICollection, IComparable, ICloneable
32
IDictionary Interface
A dictionary is an associative array It associates a key with a value and allows
a value to be retrieved by providing the key
Implements: ICollection, IEnumerable
33
IDictionary Interface
Method/Property Description
Add(object key, object value) Adds a key and value to the collection
Remove(object key) Removes the key and value pair
bool Contains(object key) True if the dictionary contains the key
IDictionaryEnumerator GetEnumerator()
Returns an enumerator
object this[object key] Gets or sets item with specified key. If the key does not exist, it is created.
ICollection Values Returns the values as a collection
ICollection Keys Returns the keys as a collection
34
Hashtables
The hashtable is a common implementation of the IDictionary interface
If the key is not an integer then the hashcode for the key is used as an index into the hashtable
Keys used with hashtables must have unique hashcode for every value
35
IDictionaryEnumerator Interface
This is the type of enumerator used with dictionaries
It implements IEnumerator Has properties
Key Returns the key for the item
Value Returns the value for the item
36
BitArray Class
Long bit strings can be difficult to store efficiently
Since data structures can be addressed on the byte level, we end up storing one bit per byte, wasting 7 bits
The BitArray class stores the bits efficiently while providing access
37
BitArray Class
The constructor is overloaded BitArray(Boolean[])
Makes a BitArray from an array of Booleans BitArray(Byte[])
Makes an array from an array of Bytes where each byte represents 8 bits
BitArray(int len) Creates a BitArray of len bytes
BitArray(int[]) Makes a BitArray from the 32 bits in each int in an array of
ints
38
BitArray Indexer
The BitArray has an indexer providing both get and setBitSet bs = new BitSet(8);bs[0] = true;Console.WriteLine(bs[1]);
There are also Get and Set methodsbool Get(int index)void Set(int index, bool value)
39
BitArray Operations
Various Boolean operations are providedBitArray And(BitArray)BitArray Or(BitArray)BitArray Xor(BitArray)BitArray Not()
You can set all of the bits at oncevoid SetAll(bool value)
40
Contents
Arrays Collections Generics Strings
41
Generics
All of the containers so far have stored data as objects This means
Containers hold any type Operations must test the type before operating on the objects in
the container When objects are removed from the container they must be cast
to their true type The programmer must remember the type of the object placed in
the container CLR must test to see that the cast is legal
42
Generics
All of this Places an extra burden on the programmer having to
remember the types Introduces new potential sources of error Forces expensive run-time type checking
What is needed is a way to make a class work with many types but Do so efficiently Enforce compile type strong type checking
43
Generics
The solution is generics! This is almost the same as the template facility
of C++ Classes and methods are parameterized with a
type Every time the class or method is used with a
new type, the compiler generates the code for that type and compiles it
This allows strong type checking at compile time
44
Generic Classes
To create a generic class, we parameterize it with one or more type parameters
The parameter types can then be used as types within the class and will be replaced with the actual types used when the class instance is created
45
Generic Array
A growable array which can hold any type
class GenericArray<T>{ T[] data;
public GenericArray(int sz) { if (sz < 1) sz = 1; data = new T[sz]; }
…} * see GenericArray
46
Creating Generic Class Instances
To create an instance of our generic array for integersGenericArray<int> iar = new GenericArray<int>(5);
This will cause the compiler to write a new class and replace every occurrence of the parameter T by int and compile this new class
47
Generic Methods
A class can also have generic methods which can work with any type
We will demonstrate this by writing a method to test the Generic Array
This method will be placed in the class containing the Main method
48
Generic Methods
static void test<E>(string id, GenericArray<E> ar, E[] data) {
for (int i = 0; i < data.Length; i++) { ar[i] = data[i]; }
for (int i = 0; i < data.Length; i++) { Console.WriteLine("{0}[{1}] = {2}",
id, i, ar[i]); } Console.WriteLine("final capacity={0}",
ar.Capacity);}
49
Generic Collections
There are actually three different namespaces for collections System.Collections
Non-generic collections with data stored as objects
System.Collections.Generic Generic collections
System.Collections.Specialized Specialized, strongly typed collections designed to work
efficiently with specific types
50
Generic Collections
Generic Class Description
Dictionary<K, V> Generic unordered dictionary
LinkedList<E> Generic doubly linked list
List<E> Generic ArrayList
Queue<E> Generic queue
SortedDictionary<K, V> Generic dictionary implemented as a tree so that elements are stored in order of the keys
SortedList<K, E> Generic binary tree implementation of a list. Can have any type of subscript. More efficient than SortedDictionary in some cases.
Stack<E> Generic stack
51
Contents
Arrays Collections Generics Strings
52
Strings
C# strings are really instances of System.String
The class implements IComparable, ICloneable, IConvertable,
IEnumerable, IEnumerable<string>, IComparable<string>, IEquatable
The class provides a large number of methods for manipulating strings
53
Creating Strings
The easiest way is to assign a string in quotesstring s = “abc”;
All builtin types have a ToString() method which can be used to convert to a stringint n = 5;string s1 = n.ToString();
Verbatim strings start with an @ symbol and do not have escape characters replaced string exact = @”ab\nc”
54
Manipulating String Contents
Strings are immutable This means that any attempt to change a
string will create a new string This has major performance implications If you will be making major changes to a
string, you should use a StringBuilder
55
Accessing String Contents
Strings have an indexer which supports get onlyString s = “abc”;
Console.WriteLine(s[1]); There is also a substring method
Substring(int startIdx);
Substring(int start, int len); Find the string length with Length property
Length
56
Comparing Strings
A static method to compare two strings static int compare(string, string);
An instance method to compare this to another string int CompareTo(string);
Static & instance versions of Equals int Equals(string) static bool Equals(string, string)
57
Comparing Strings
Comparing the starts and ends of strings bool startsWith(string) bool endsWith(string)
58
Searching Strings
To find the first index of a char int IndexOf(char) int IndexOf(char, int startIndex)
To find the first index of a string int IndexOf(string) int IndexOf(string, int startIndex)
To find the last index of a char int LastIndexOf(char) int LastIndexOf(char, int startIndex)
To find the last index of a string int LastIndexOf(string) int LastIndexOf(string, int startIndex)
59
Searching Strings
Find the first occurrence of any of a set of characters int IndexOfAny(char[]) int IndexOfAny(char[], int startIndex)
Find the last occurrence of any of a set of characters int LastIndexOfAny(char[]) int LastIndexOfAny(char[], int startIndex)
60
Handling Spaces
To remove a set of chars from start or end TrimStart(chars[]) TrimEnd(chars[])
To remove spaces from both ends Trim()
To remove a set of chars from both ends Trim(char[])
To pad spaces on either side PadRight(int totalLength) PadLeft(int totalLength)
61
Converting Case
ToUpper() ToLower()
62
Splitting and Joining
To split a string into an array of strings at every occurrence of a separator charstring[] split(string, char[])
To join an array of strings into one string with a separator string between every pair of stringstring join(string sep, string[])
63
Formatting
To format an object into a string string format(string fmt, object)
The format string is the same as used by WriteLine where an argument is referenced by an index string s = s1.format(“{0:fmt}”, i); Where fmt is one of the format codes on the next
page
64
Formatting
Format Meaning
C Currency
D Decimal
F Fixed point
E Scientific
P Percent
X Hexadecimal
D Long date
65
StringBuilder Class
The trouble with strings is that they are immutable
Every time you have to concatenate two strings, a new string is produced
This creates a huge amount of memory allocation and garbage collection
The StringBuilder is a class which can build a string much more efficiently
66
StringBuilder Class
To create oneStringBuilder()StringBuilder(int capacity)
If the capacity of the StringBuilder is exceeded, new space is automatically allocated
Ensuring sufficient capacity at the start is more efficient than forcing reallocation
67
Appending to a StringBuilder
StringBuilder Append(anyPrimitive) This produces a string representation of the primitive
and appends it onto the end of the contents of the StringBuilder
This can be used to append strings too
You can also append a formatted string similar to the formatting done by WriteLinesb.AppendFormat("2) {0}, {1}", var1, var2);
68
Appending to a StringBuilder
You can also append a line using the default line terminatorAppendLine()AppendLine(string)
Without a parameter, it just inserts a line terminator
With a parameter, the string is appended followed by the line terminator
69
Getting the Content
Building a string is useless unless you can retrieve it
To get the whole StringBufferstring ToString()
To get just part of the StringBufferstring ToString(int start, int len)