• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 268
  • Last Modified:

Tips on using a hashtable

Hi,

I need what amounts to a two dimensional array of doubles, except the lookup handles look like "B12" and K21", instead of integers.  So I was planning on using a hashtable.  Except it's not to clear where to start.

I see that each object I pass into the hashtable will override "Equals" and "GetHashCode()".  But I think I'll need more than that to get it right. For example, wouldn't the object I pass into the hashtable have two handles?  (in this case, B12 and K21?)

If you have any advice or expertise in hashtables, it would be much appreciated.

Thanks,
Bob
0
ba272
Asked:
ba272
  • 3
  • 2
1 Solution
 
PerryDKCommented:
You way want to modify the GetHashCode to better suit your data but here is a basic implementation of what you ask for.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace HashTableExample
{
      /// <summary>
      /// Summary description for Form1.
      /// </summary>
      public class frmMain : System.Windows.Forms.Form
      {
            private System.Windows.Forms.Label label1;
            private System.Windows.Forms.Label label2;
            private System.Windows.Forms.TextBox txtKey1;
            private System.Windows.Forms.TextBox txtKey2;
            private System.Windows.Forms.Label label3;
            private System.Windows.Forms.TextBox txtValue;
            private System.Windows.Forms.Button btnGetValue;
            private System.Windows.Forms.Button btnSetValue;
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.Container components = null;

            public frmMain()
            {
                  //
                  // Required for Windows Form Designer support
                  //
                  InitializeComponent();

                  //
                  // TODO: Add any constructor code after InitializeComponent call
                  //
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.label1 = new System.Windows.Forms.Label();
                  this.label2 = new System.Windows.Forms.Label();
                  this.txtKey1 = new System.Windows.Forms.TextBox();
                  this.txtKey2 = new System.Windows.Forms.TextBox();
                  this.label3 = new System.Windows.Forms.Label();
                  this.txtValue = new System.Windows.Forms.TextBox();
                  this.btnGetValue = new System.Windows.Forms.Button();
                  this.btnSetValue = new System.Windows.Forms.Button();
                  this.SuspendLayout();
                  //
                  // label1
                  //
                  this.label1.Location = new System.Drawing.Point(8, 8);
                  this.label1.Name = "label1";
                  this.label1.TabIndex = 0;
                  this.label1.Text = "Key1";
                  //
                  // label2
                  //
                  this.label2.Location = new System.Drawing.Point(8, 40);
                  this.label2.Name = "label2";
                  this.label2.TabIndex = 1;
                  this.label2.Text = "Key2";
                  //
                  // txtKey1
                  //
                  this.txtKey1.Location = new System.Drawing.Point(120, 8);
                  this.txtKey1.Name = "txtKey1";
                  this.txtKey1.TabIndex = 2;
                  this.txtKey1.Text = "";
                  //
                  // txtKey2
                  //
                  this.txtKey2.Location = new System.Drawing.Point(120, 40);
                  this.txtKey2.Name = "txtKey2";
                  this.txtKey2.TabIndex = 3;
                  this.txtKey2.Text = "";
                  //
                  // label3
                  //
                  this.label3.Location = new System.Drawing.Point(8, 72);
                  this.label3.Name = "label3";
                  this.label3.TabIndex = 4;
                  this.label3.Text = "Value";
                  //
                  // txtValue
                  //
                  this.txtValue.Location = new System.Drawing.Point(120, 72);
                  this.txtValue.Name = "txtValue";
                  this.txtValue.TabIndex = 5;
                  this.txtValue.Text = "";
                  //
                  // btnGetValue
                  //
                  this.btnGetValue.Location = new System.Drawing.Point(24, 112);
                  this.btnGetValue.Name = "btnGetValue";
                  this.btnGetValue.TabIndex = 6;
                  this.btnGetValue.Text = "Get Value";
                  this.btnGetValue.Click += new System.EventHandler(this.btnGetValue_Click);
                  //
                  // btnSetValue
                  //
                  this.btnSetValue.Location = new System.Drawing.Point(120, 112);
                  this.btnSetValue.Name = "btnSetValue";
                  this.btnSetValue.TabIndex = 7;
                  this.btnSetValue.Text = "Set Value";
                  this.btnSetValue.Click += new System.EventHandler(this.btnSetValue_Click);
                  //
                  // frmMain
                  //
                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                  this.ClientSize = new System.Drawing.Size(384, 302);
                  this.Controls.Add(this.btnSetValue);
                  this.Controls.Add(this.btnGetValue);
                  this.Controls.Add(this.txtValue);
                  this.Controls.Add(this.label3);
                  this.Controls.Add(this.txtKey2);
                  this.Controls.Add(this.txtKey1);
                  this.Controls.Add(this.label2);
                  this.Controls.Add(this.label1);
                  this.Name = "frmMain";
                  this.Text = "Hash Table Example";
                  this.ResumeLayout(false);

            }
            #endregion

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                  Application.Run(new frmMain());
            }

            private void btnGetValue_Click(object sender, System.EventArgs e)
            {
                  TwoKeys twoKeys = new TwoKeys(txtKey1.Text.Trim(), txtKey2.Text.Trim());
                  if(hashtable.ContainsKey(twoKeys))
                  {
                        txtValue.Text = hashtable[twoKeys].ToString();
                  }
                  else
                  {
                        txtValue.Text = "Not Found!";
                  }
            }

            private void btnSetValue_Click(object sender, System.EventArgs e)
            {
                  TwoKeys twoKeys = new TwoKeys(txtKey1.Text.Trim(), txtKey2.Text.Trim());
                  if(hashtable.ContainsKey(twoKeys))
                  {
                        hashtable[twoKeys] = Convert.ToDouble(txtValue.Text);
                  }
                  else
                  {
                        hashtable.Add(twoKeys, Convert.ToDouble(txtValue.Text));
                  }

            }

            private Hashtable hashtable = new Hashtable();

            private class TwoKeys
            {
                  public TwoKeys(string key1, string key2)
                  {
                        this.key1 = key1;
                        this.key2 = key2;
                  }

                  public override bool Equals(object obj)
                  {
                        TwoKeys rhs = obj as TwoKeys;
                        if(rhs == null)
                        {
                              return base.Equals(obj);
                        }
                        else
                        {
                              if(Key1 == rhs.Key1 && Key2 == rhs.Key2)
                                    return true;
                              else
                                    return false;
                        }
                  }

                  public override int GetHashCode()
                  {
                        return 1000 * Key1.GetHashCode() + Key2.GetHashCode();
                  }



                  public string Key1
                  {
                        get
                        {
                              return key1;
                        }
                  }
                  private string key1;

                  public string Key2
                  {
                        get
                        {
                              return key2;
                        }
                  }
                  private string key2;
            }
      }
}
0
 
ba272Author Commented:
Wow!  That's perfect.

Thanks.
0
 
ba272Author Commented:
I was intending to store two doubles for each cell, but when I saw your code, decided it would be most easy to save the two as a single comma delimited string.  But now I think it might cost me memory, which could get costly since I expect to have ini excess of 75,000 items in the hashtable.  So that brings me to ask, how would I go about storing two doubles for each TwoKey object?

Thanks again for the help.
0
 
PerryDKCommented:
create a struct or a class to hold the data you want to store with an associated key.  Here is code below to store 2 doubles associated with 2 keys

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace HashTableExample
{
      /// <summary>
      /// Summary description for Form1.
      /// </summary>
      public class frmMain : System.Windows.Forms.Form
      {
            private System.Windows.Forms.Label label1;
            private System.Windows.Forms.Label label2;
            private System.Windows.Forms.TextBox txtKey1;
            private System.Windows.Forms.TextBox txtKey2;
            private System.Windows.Forms.Label label3;
            private System.Windows.Forms.TextBox txtValue;
            private System.Windows.Forms.Button btnGetValue;
            private System.Windows.Forms.Button btnSetValue;
            private System.Windows.Forms.TextBox txtValue2;
            private System.Windows.Forms.Label label4;
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.Container components = null;

            public frmMain()
            {
                  //
                  // Required for Windows Form Designer support
                  //
                  InitializeComponent();

                  //
                  // TODO: Add any constructor code after InitializeComponent call
                  //
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.label1 = new System.Windows.Forms.Label();
                  this.label2 = new System.Windows.Forms.Label();
                  this.txtKey1 = new System.Windows.Forms.TextBox();
                  this.txtKey2 = new System.Windows.Forms.TextBox();
                  this.label3 = new System.Windows.Forms.Label();
                  this.txtValue = new System.Windows.Forms.TextBox();
                  this.btnGetValue = new System.Windows.Forms.Button();
                  this.btnSetValue = new System.Windows.Forms.Button();
                  this.txtValue2 = new System.Windows.Forms.TextBox();
                  this.label4 = new System.Windows.Forms.Label();
                  this.SuspendLayout();
                  //
                  // label1
                  //
                  this.label1.Location = new System.Drawing.Point(8, 8);
                  this.label1.Name = "label1";
                  this.label1.TabIndex = 0;
                  this.label1.Text = "Key1";
                  //
                  // label2
                  //
                  this.label2.Location = new System.Drawing.Point(8, 40);
                  this.label2.Name = "label2";
                  this.label2.TabIndex = 1;
                  this.label2.Text = "Key2";
                  //
                  // txtKey1
                  //
                  this.txtKey1.Location = new System.Drawing.Point(120, 8);
                  this.txtKey1.Name = "txtKey1";
                  this.txtKey1.TabIndex = 2;
                  this.txtKey1.Text = "";
                  //
                  // txtKey2
                  //
                  this.txtKey2.Location = new System.Drawing.Point(120, 40);
                  this.txtKey2.Name = "txtKey2";
                  this.txtKey2.TabIndex = 3;
                  this.txtKey2.Text = "";
                  //
                  // label3
                  //
                  this.label3.Location = new System.Drawing.Point(8, 72);
                  this.label3.Name = "label3";
                  this.label3.TabIndex = 4;
                  this.label3.Text = "Value";
                  //
                  // txtValue
                  //
                  this.txtValue.Location = new System.Drawing.Point(120, 72);
                  this.txtValue.Name = "txtValue";
                  this.txtValue.TabIndex = 5;
                  this.txtValue.Text = "";
                  //
                  // btnGetValue
                  //
                  this.btnGetValue.Location = new System.Drawing.Point(24, 136);
                  this.btnGetValue.Name = "btnGetValue";
                  this.btnGetValue.TabIndex = 6;
                  this.btnGetValue.Text = "Get Value";
                  this.btnGetValue.Click += new System.EventHandler(this.btnGetValue_Click);
                  //
                  // btnSetValue
                  //
                  this.btnSetValue.Location = new System.Drawing.Point(128, 136);
                  this.btnSetValue.Name = "btnSetValue";
                  this.btnSetValue.TabIndex = 7;
                  this.btnSetValue.Text = "Set Value";
                  this.btnSetValue.Click += new System.EventHandler(this.btnSetValue_Click);
                  //
                  // txtValue2
                  //
                  this.txtValue2.Location = new System.Drawing.Point(120, 104);
                  this.txtValue2.Name = "txtValue2";
                  this.txtValue2.TabIndex = 9;
                  this.txtValue2.Text = "";
                  //
                  // label4
                  //
                  this.label4.Location = new System.Drawing.Point(8, 104);
                  this.label4.Name = "label4";
                  this.label4.TabIndex = 8;
                  this.label4.Text = "Value 2";
                  //
                  // frmMain
                  //
                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                  this.ClientSize = new System.Drawing.Size(384, 302);
                  this.Controls.Add(this.txtValue2);
                  this.Controls.Add(this.label4);
                  this.Controls.Add(this.btnSetValue);
                  this.Controls.Add(this.btnGetValue);
                  this.Controls.Add(this.txtValue);
                  this.Controls.Add(this.label3);
                  this.Controls.Add(this.txtKey2);
                  this.Controls.Add(this.txtKey1);
                  this.Controls.Add(this.label2);
                  this.Controls.Add(this.label1);
                  this.Name = "frmMain";
                  this.Text = "Hash Table Example";
                  this.ResumeLayout(false);

            }
            #endregion

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                  Application.Run(new frmMain());
            }

            private void btnGetValue_Click(object sender, System.EventArgs e)
            {
                  TwoKeys twoKeys = new TwoKeys(txtKey1.Text.Trim(), txtKey2.Text.Trim());
                  if(hashtable.ContainsKey(twoKeys))
                  {
                        TwoValues tv = (TwoValues)hashtable[twoKeys];
                        txtValue.Text = tv.value1.ToString();
                        txtValue2.Text = tv.value2.ToString();
                  }
                  else
                  {
                        txtValue.Text = "Not Found!";
                        txtValue2.Text = "Not Found!";
                  }
            }

            private void btnSetValue_Click(object sender, System.EventArgs e)
            {
                  TwoKeys twoKeys = new TwoKeys(txtKey1.Text.Trim(), txtKey2.Text.Trim());
                  if(hashtable.ContainsKey(twoKeys))
                  {
                        hashtable[twoKeys] = new TwoValues(Convert.ToDouble(txtValue.Text), Convert.ToDouble(txtValue2.Text));
                  }
                  else
                  {
                        hashtable.Add(twoKeys, new TwoValues(Convert.ToDouble(txtValue.Text), Convert.ToDouble(txtValue2.Text)));
                  }

            }

            private Hashtable hashtable = new Hashtable();

            private class TwoKeys
            {
                  public TwoKeys(string key1, string key2)
                  {
                        this.key1 = key1;
                        this.key2 = key2;
                  }

                  public override bool Equals(object obj)
                  {
                        TwoKeys rhs = obj as TwoKeys;
                        if(rhs == null)
                        {
                              return base.Equals(obj);
                        }
                        else
                        {
                              if(Key1 == rhs.Key1 && Key2 == rhs.Key2)
                                    return true;
                              else
                                    return false;
                        }
                  }

                  public override int GetHashCode()
                  {
                        int result = 1000 * Key1.GetHashCode() + Key2.GetHashCode();
                        return result;
                  }



                  public string Key1
                  {
                        get
                        {
                              return key1;
                        }
                  }
                  private string key1;

                  public string Key2
                  {
                        get
                        {
                              return key2;
                        }
                  }
                  private string key2;
            }

            private struct TwoValues
            {
                  public TwoValues(double value1, double value2)
                  {
                        this.value1 = value1;
                        this.value2 = value2;
                  }

                  public double value1;
                  public double value2;
            }
      }
}
0
 
ba272Author Commented:
Thanks.  Got it.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now