Hashtables con clave compleja

Un hashtable es un tipo de coleccion que relaciona un valor Clave con un Valor. Estos pares se almacenan en la coleccion basados en un valor Hash de la clave. Dicho valor Hash tiene las siguientes caracteristicas:

  • Es un entero de 32 bits.
  • Debe ser ?nico para cada Clave.
  • No debe de variar en la vida del Hashtable.
  • Si dos objetos representan el mismo valor, deben devolver el mismo Hash.
  • Y debe tener un valor cuya distribucion variable para todos los hashes del Hashtable sea lo mas uniforme posible.

Teniendo en cuenta esto, todos los objetos de .NET ofrecen una funcion que devuelve el codigo hash propio, que es el que utiliza el Hashtable para ordenar por la clave.

Public Overridable Function GetHashCode() As Integer

La implementacion por defecto no garantiza todas las caracteristicas anteriormente comentadas que deberia tener todo c?digo hash, es por ello que es recomendable implementar un generador de hash propio siempre que la clase vaya a ser utilizada como clave dentro de un Hashtable.

Esto es sobre todo de vital importancia cuando la clave es una clave compuesta de 2 valores. Por ejemplo, supongamos que la manera de trabajar de un usuario es que debe visitar a un cliente cada d?a y en cada visita debe rellenar un factura. Queremos guardar para cada dia y cliente (esta seria la clave), una factura (este es el valor).

Lo primero: es importante definir que la clave no va a ser modificada durante la vida del Hashtable. Una vez creada la hashtable, no podemos decir que tal dia se visitara a otro cliente distinto.

Lo segundo: Codificamos la clase clave:

Public Class CHashtableKey

Protected m_objCliente As CCliente

Public ReadOnly Property Cliente() As CCliente

Get

Return m_objCliente

End Get

End PropertyProtected m_dFecha As Date

Public ReadOnly Property Fecha() As Date

Get

Return m_dFecha

End Get

End Property

Public Sub New(ByVal objCliente As CCliente, ByVal dFecha As Date)

m_objCliente = objCliente

m_dFecha = dFecha

End Sub



En Clase

Esta clase define la clave del hashtable. Pero debemos de implementar nuestro propio HashCode ya que si no lo hacemos el Hashtable no funcionaria. La implementacion por defecto del HashCode de la clase anterior devuelve una referencia a la instancia. Lo que va a pasar es que cuando insertemos la clave no podremos crear un objeto clave nuevo igual para buscar ya que el nuevo objeto tendra un valor de instancia nuevo y por ende un codigo Hash diferente.

Aqui es donde radica la dificultad. Debemos de generar un HashCode que nos asegure que sea unico y que este bien distribuido en todo el Hashtable.

Public Overloads Overrides Function GetHashCode() As Integer

Return m_dFecha.GetHashCode * NumClientes + m_objCliente.Codigo

End Function

Si el Codigo del cliente fuese desde 0 a NumClientes y que se metiesen todos los clientes en el Hashtable conseguiriamos una distribucion uniforme del c?digo hash en el Hashtable.

Por otro lado conviene tambien redefinir la funcion Equals en base los valores que contiene y asi cumplir la norma que impone que dos instancias de un objeto son iguales para el Hashtable en el momento que representen la misma clave:

Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean

Dim objCliente As CHashtableKey = obj

Return (m_objCliente.Codigo = objCliente.Cliente.Codigo) And (m_dFecha = obj.Fecha)

End Function

Hay mucho que decir acerca de este tema:

- ?Nos fiamos de los c?digos hash de los tipos predefinidos?

- ?Hasta que punto queda bien definido el hash devuelto por un objeto compuesto para todos los casos en que se utilice?

- En el ejemplo: ?Nos podemos fiar del hash devuelto por la fecha para generar nuestro propio hash?

etc, etc.

Todavía no hay comentarios

Enviar un comentario nuevo

El contenido de este campo se mantiene privado y no se mostrará públicamente.
  • Etiquetas HTML permitidas: <a> <blockquote> <br> <cite> <code> <dd> <div> <dl> <dt> <em> <h1> <h2> <h3> <h4> <h5> <h6> <hr> <img> <li> <ol> <p> <pre> <span> <strong> <swf> <table> <tbody> <td> <th> <tr> <ul>
    Allowed Style properties: background-color, background-image, border, border-bottom, border-bottom-color, border-bottom-style, border-bottom-width, border-color, border-left, border-left-color, border-left-style, border-left-width, border-right, border-right-color, border-right-style, border-right-width, border-spacing, border-style, border-top, border-top-color, border-top-style, border-top-width, border-width, color, direction, font, font-family, font-size, font-style, font-variant, font-weight, height, left, line-height, list-style-type, margin, margin-bottom, margin-left, margin-right, margin-top, padding, padding-bottom, padding-left, padding-right, padding-top, right, text-align, text-decoration, top, width
  • Syntax highlight code surrounded by the {syntaxhighlighter OPTIONS}...{/syntaxhighlighter} tags.
  • E-Mail addresses are hidden with reCAPTCHA Mailhide.

Más información sobre opciones de formato

CAPTCHA
Esta pregunta es para comprobar si eres un ser humano y evitar el envío automático desde sistemas de spam