Arraylist searching question

C

C Downey

Hello:

I have an arraylist storing some very basic objects.

The object is very basic, it has 2 properties : ID, and COUNT

Before I add an object to the arraylist, I want to check if an object with
that same ID already exists in the arraylist.

If it does, I would like to increase the count of the matching object inside
of the arraylist by 1, otherwise I want to add the new object.

How would I go about finding out if that object is already added in my
arraylist? And how would I increase the count?

Any advice and sample code would be greatly apreciated!
 
A

Alex Papadimoulis

Hi Colleen,

The ArrayList has a Contains( item ) method that returns a boolean
indicating whether the item is in the list. this method uses Object.Equals
comparison, so if you want your object to be found, it will need to override
that function. Here's an example:

Class simpleObj
public ID as integer;
public Count as integer;
public overrides function Equals( obj as simpleObj) as boolean
return obj.ID = ID
end function
End Class

dim myList as New ArrayList
myList.Add(simpleObj1)
if myList.Contains(simpleObj2) then
idx = myList.IndexOf(simpleObj2)
myList(idx).Count += 1
else
myList.Add(simpleObject2)
end if

Good Luck!

-- Alex Papadimoulis
 
B

bruce barker

you should use a Hashtable, which has much better search performance.

-- bruce (sqlwork.com)
 
C

C Downey

Thanks for your reply! It makes sense and is very clever however I am
having troubles implementing it. The code runs but the overloaded method
equals always seems to return false.
When I put a breakpoint in the overloaded "Equals" the code never seems to
get there.
Any ideas?


My code is :


While dr.Read
ecMO = New ecMatchingOcc
ecMO.OccID = dr(0)
ecMO.Matches = dr(1)
If al.Contains(ecMO) Then
idx = al.IndexOf(ecMO)
al(idx).Matches += 1
Else
al.Add(ecMO)
End If
End While

' -- ============= simple class
Public Class ecMatchingOcc ' simple class to store matching Occupational
profiles
Private _occID As Int32
Private _matches As Int32

Public Overloads Function Equals(ByVal obj As ecMatchingOcc) As Boolean
Return obj.OccID = _occID ' doesnt seem to be executed when i put a
breakpoint here
End Function

Public Property OccID() As Int32
Get
Return _occID
End Get
Set(ByVal Value As Int32)
_occID = Value
End Set
End Property

Public Property Matches() As Int32
Get
Return _matches
End Get
Set(ByVal Value As Int32)
_matches = Value
End Set
End Property
End Class
 
C

C Downey

You'll notice I used overloads instead of overrides

When I use overrides I get an error message:

function 'Equals' shadows an overloadable member declared in the bass class
'Object'

So I switched to overloads instead...
 
A

Alex Papadimoulis

Colleen,

The Arraylist will not call your Equals function, since it is not
Object.Equals. What you should do is ...

Public Overrides Function Equals(ByVal obj As object) As Boolean
If TypeOf obj Is ecMatchingOcc Then Return Equals(
DirectCast(obj,ecMatchingOcc) )
Return False
End Function
Public Overloads Function Equals(ByVal obj As ecMatchingOcc) As Boolean
Return obj.OccID = _occID ' doesnt seem to be executed when i put a
End Function

... that way, you are ovveriding the base method (which accepts an Object as
a paramter), and overloading it with your own, strongly typed method.

-- Alex Papadimoulis
 
A

Alex Papadimoulis

Colleen,

Oops! I forgot the "Overloads" keyword. Here's what your class should have:

Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean
If TypeOf obj Is ecMatchingOcc Then _
Return Equals(DirectCast(obj, ecMatchingOcc))
End Function
Public Overloads Function Equals(ByVal obj As ecMatchingOcc) As Boolean
Return obj.OccID = _occID
End Function

Now this will work for ya :)

Note, another function you may want to override is the GetHashCode function.
This is a good idea when overloading the equals function. Your GetHashCode
should probably return your OccID. This is pretty important for HashTables
and other things that use it.

-- Alex Papadimoulis
 
C

C Downey

Hi Alex -

My exact code in my class is below. I still get the error message "function
Equals shadows an overloadable member declared in the base class 'object'".
The error is given to me on the first "Equals" function. I have looked all
over the web but have found no explanation for this. If this works, I would
also like to override the sort method - this should be similar?

Thanks!


' this is the code within my "simple" class...it only has 2 properties
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If TypeOf obj Is ecMatchingOcc Then
Return Equals(DirectCast(obj, ecMatchingOcc))
Else
Return False
End If
End Function
Public Overloads Function Equals(ByVal obj As ecMatchingOcc) As
Boolean
Return obj.OccID = _occID
End Function
 
A

Alex Papadimoulis

Colleen,

To sort your ArrayList by the count property on your object, your class
needs to implement the IComparable interface:
Public Class ecMatchingOcc
Implements IComparable
Public Function CompareTo(ByVal obj As Object) As Integer Implements
System.IComparable.CompareTo
If Not TypeOf obj Is ecMatchincOcc Then Throw New
ArgumentException("obj")
Return DirectCast(obj,ecMatchingOcc).Matches.CompareTo( Me.Matches )
End Function
End Class

CompareTo returns -1 for Less Than, 0 for Equal, and 1 for greater than.
But, Integer implements it, so just use it's method.

As for why you should override GetHashCode, here's a snippet from the
documentation:
"The default implementation of GetHashCode does not guarantee uniqueness or
consistency; therefore, it must not be used as a unique object identifier
for hashing purposes. Derived classes must override GetHashCode with an
implementation that returns a unique hash code. For best results, the hash
code must be based on the value of an instance field or property, instead of
a static field or property."

Since your business logic defines equality on ecMatchingOcc as having the
same ID, two separate instances of ecMatchingOcc with the same ID should
produce the same hashcode. While it's not required, it's a good design
practice.

-- Alex Papadimoulis
 
C

C Downey

That worked great!

Sorry - one more hopefully quick question. How could I override the sort
method so I can sort the "count" property?

I dont really understand why I would override the GetHashCode function
either - can you give me a quick explanation?

Thank you very much, you have been a great help!

Colleen
 
C

C Downey

Hi Alex,

I think I got it, although I dont 100% follow the code.

Implements IComparable

Private _occID As Int32
Private _matches As Int32

Public Overloads Function CompareTo(ByVal obj As Object) As Integer
Implements IComparable.CompareTo

If TypeOf obj Is ecMatchingOcc Then
Dim ecMO As ecMatchingOcc = CType(obj, ecMatchingOcc)

Return _matches.CompareTo(ecMO.Matches)
End If

Throw New ArgumentException("object is not a match!!!")

End Function
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top