14.5. Custom Collections

The .NET Collections library does not contain nearly as many classes and interfaces as the java.util package. The Collections library currently has no support whatsoever for sets. Sometimes you must roll your own collections. You do so by implementing some of the System.Collections interfaces.

In the next two listings we will try to write a C# version of the java.util.LinkedHashMap, a special HashMap introduced in JDK 1.4. Unlike the ordinary HashMap, this new one stores the key-value pairs in the order in which they are added to the map. The ability to retain this order is critical when, say, you are fetching data from a database and that data is already sorted according to certain criteria and you don't want to destroy the sort order by putting the fetched entries in an ordinary HashMap.

Listing 14.11 shows the KeySet class. Following the pattern of a java.util.Map, the keys of a HashMap form a Set, and so to create our HashMap we first need a data structure for storing the unique keys.

Listing 14.11. The KeySet Class (C#)
public class KeySet : IList {
  ArrayList innerList;
  public KeySet() {
    innerList = new ArrayList();
  }
  public void Add (object o) {
    if (!innerList.Contains(o)) innerList.Add(o);
  }
  public void Clear () {
    innerList.Clear();
  }
  public bool Contains (object o) {
    return innerList.Contains(o);
  }
  public int IndexOf (object o) {
    return innerList.IndexOf(o);
  }
  public void Insert (int index, object o) {
    if (!innerList.Contains(o)) {
      innerList.Insert(index, o);
    }
  }
  public void Remove (object o) {
    innerList.Remove(o);
  }
  public void RemoveAt (int index) {
    innerList.RemoveAt(o);
  }
}

The KeySet class is a wrapper over the ArrayList class. KeySet checks for the existence of an entry in the list before adding the entry to the list. In this way, the ArrayList always contains unique values.

Next, we use the KeySet class to write the C# LinkedHashtable (Listing 14.12). Our hash table will merely wrap C#'s Hashtable and in addition will maintain an internal KeySet object to make sure the keys are not reordered.

Listing 14.12. The LinkedHashtable Class (C#)
using System;
using System.Collections;

public class LinkedHashtable : IDictionary {
  public static void Main(string[] args) {
    LinkedHashtable lh = new LinkedHashtable();
      Console.WriteLine("**** LinkedHashtable **** ");
    print(lh);
    Hashtable map = new Hashtable();
    Console.WriteLine("**** Hashtable **** ");
    print(map);
  }
  private static void print(IDictionary map) {
    for (int i =0; i < 10; ++i)
      map.Add(i, 10*i);
    foreach (object key in map.Keys) {
      Console.WriteLine("Key ="+key+" Value = "  ap[key]);
    }
  }

  KeySet keys = new KeySet();
  Hashtable table;
  public LinkedHashtable () { table = new Hashtable(); }
  public void Add(object key, object val) {
    table.Add(key, val);
    keys.Add(key);
  }
  public void Clear() {
    table.Clear();
    keys.Clear();
  }
  public bool Contains(object key) {
    return table.Contains(key);
  }
  public IDictionaryEnumerator GetEnumerator() {
    return table.GetEnumerator();
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return ((IEnumerable)table).GetEnumerator();
  }

  public void Remove(object key) {
    table.Remove(key);
    keys.Remove(key);
  }
  public bool IsSynchronized {
    get {
      return table.IsSynchronized;
    }
  }
  public object SyncRoot {
    get {
      return table.SyncRoot;
    }
  }
  public int Count {
    get {
      return table.Count;
    }
  }
  public bool IsFixedSize {
    get {
      return table.IsFixedSize;
    }
  }
  public bool IsReadOnly {
    get {
      return table.IsReadOnly;
    }
  }
  public ICollection Keys {
    get {
      return keys;
    }
  }
  public ICollection Values {
    get {
      return table.Values;
    }
  }
  public void CopyTo(System.Array array, int index) {
    table.CopyTo(array, index) ;
  }
  public object this[object index] {
    get {
      return table[index];
    }
    set {
      table[index] = value;
    }
  }

}

The output of Listing 14.12 is as follows:

**** LinkedHashtable ****
Key =0 Value = 0
Key =1 Value = 10
Key =2 Value = 20
Key =3 Value = 30
Key =4 Value = 40
Key =5 Value = 50
Key =6 Value = 60
Key =7 Value = 70
Key =8 Value = 80
Key =9 Value = 90
**** Hashtable ****
Key =9 Value = 90
Key =8 Value = 80
Key =7 Value = 70
Key =6 Value = 60
Key =5 Value = 50
Key =4 Value = 40
Key =3 Value = 30
Key =2 Value = 20
Key =1 Value = 10
Key =0 Value = 0

You can see from the output that the Hashtable class does not retain the order in which the entries were inserted, but LinkedHashtable does.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.90.131