En el anterior post estuve hablando de los ArrayList en VisualBasic.NET y comenté que para que el método BinarySearch funcione es necesario que los objetos dentro del ArrayList estén ordenados. Al menos para que funcione correctamente, claro.
Una de las maneras de ordenarlos era utilizando el método Sort. Otra consistía en añadir los objetos mediante el método Insert y hacerlo en la posición adecuada para que el ArrayList estuviera siempre ordenado. Así que en cualquier caso necesitaremos que los objetos que llenan el ArrayList se puedan comparar. Si lo hacemos tirando de método Sort porque tendrán que poder ordenarse. Si no, porque BinarySearch necesita poder comparar dos objetos para determinar si son el mismo en función de los criterios que le digamos.
En mi ejemplo teníamos un ArrayList lleno de personas que eran instancias de la clase clsPerson. Así que vamos a ver cómo hacer que dos objetos clsPerson se puedan comparar. Para ello ya dije que tenemos dos alternativas: mediante una clase externa que implemente un IComparer, o haciendo que clsPerson implemente IComparable.
En este post explico el segundo sistema: hacer que clsPerson implemente IComparable. En realidad es muy sencillo, puesto que sólo tenemos que crear la clase como lo haríamos en circunstancias normales y tener en cuenta que tenemos que hacerle dos pequeñas modificaciones:
1) Tras la definición de la clase (Public Class clsPerson) informarle que va a ser una clase que implementará IComparable (Implements IComparable).
2) Crearle un método CompareTo para poder comparar la instancia actual con otra instancia de clsPerson. De hecho al pulsar Enter después de añadir el Implements IComparable ya se nos creará el método CompareTo automáticamente.
Adjunto código básico:
' Author: Albert Mata (www.albertmata.net)
' Date: 20080622
' Description: Class to show how to work with ArrayList.
'--------------------------------------------------------------------
Public Class clsPerson
Implements IComparable 'in order to be able to be compared
'----------------------------------------------------------------
' Attributes.
'----------------------------------------------------------------
Public Name As String
Public Age As Integer
'----------------------------------------------------------------
' Constructor method.
'----------------------------------------------------------------
Public Sub New(ByVal Name As String, ByVal Age As Integer)
Me.Name = Name
Me.Age = Age
End Sub
'----------------------------------------------------------------
' Comparator method. Returns:
' -1 if current instance is "smaller" than parameter object.
' 0 if current instance is "equal to" parameter object.
' +1 if current instance is "bigger" than parameter object.
'----------------------------------------------------------------
Public Function CompareTo(ByVal obj As Object) As Integer _
Implements System.IComparable.CompareTo
'Converting parameter object to clsPerson type.
Dim Compare As clsPerson = CType(obj, clsPerson)
'First criterium to be used to compare.
Dim Result As Integer = Me.Name.CompareTo(Compare.Name)
'When draw happens, next criterium to be used to compare.
If Result = 0 Then
Result = Me.Age.CompareTo(Compare.Age)
End If
'Returning result.
Return Result
End Function
End Class
Como se puede ver, el método CompareTo no entraña dificultad. Simplemente hay que ir dándole criterios con los que poder comparar la instancia sobre la que trabajamos con otra instancia que la función recibirá como argumento. En principio en nuestro código no necesitaremos invocar directamente esta función, ya que es algo que hará de manera interna el método Sort o BinarySearch del ArrayList que contiene los objetos de tipo clsPerson. No obstante como método normal y corriente que es nada nos impide utilizarlo también de manera directa. Para ella creamos por ejemplo 5 objetos con las instrucciones:
Dim P2 As New clsPerson("Morgan", 32)
Dim P3 As New clsPerson("Albert", 35)
Dim P4 As New clsPerson("Morgan", 32)
Dim P5 As New clsPerson("Zoe", 17)
Y a continuación podemos realizar llamadas y obtener estos resultados:
P5.CompareTo(P1) returns... 1
P3.CompareTo(P1) returns... 1
P2.CompareTo(P4) returns... 0
Lo que nos dice que Albert-29 es más “pequeño” que Morgan-32 (ojo, la ordenación va por nombre, no por edad), Zoe-17 es más “grande” que Albert-29, Albert-35 es más “grande” que Albert-29 (si la ordenación por nombre no puede discernir, pasa a las edades) y finalmente Morgan-32-P2 es igual a Morgan-32-P4, lo cual es correcto porque ambos objetos son iguales (es sólo un ejercicio teórico, en realidad no existirían los dos objetos porque de hecho sería un objeto duplicado).
Últimos comentarios
RSS