ArrayList?

  • Thread starter Thread starter Kym
  • Start date Start date
K

Kym

Hey,
I have an arraylist which I have added a number of objects to (all the same
type of object), I need to be able to check if the array already contain the
object before adding it, I have tried something like...

if Not myArray.contains(newObject) then
myArray.Add(newObject)
end if

This will work with a string object but not a user defined object.
I can get things to work by using a HashTable but I'm sure I have done this
before using an ArrayList.
Can anyone let me know If and How to do this.

All the Best
Kym
 
Kym said:
Hey,
I have an arraylist which I have added a number of objects to (all
the same type of object), I need to be able to check if the array
already contain the object before adding it, I have tried something
like...

if Not myArray.contains(newObject) then
myArray.Add(newObject)
end if

This will work with a string object but not a user defined object.
I can get things to work by using a HashTable but I'm sure I have
done this before using an ArrayList.
Can anyone let me know If and How to do this.


Arraylist.contains should work with other object types, too. If tried it
again (with String, Point, Form) and it works. How did you notice that it
does not work?


Armin
 
Why not just use a generic list? Something like

dim myList as new List(Of UserDefinedObject)()

if not myList.Contains(newObject) then
myList.Add(newObject)
end if

Thanks,

Seth Rowe
 
A couple of things to try here.

1) have your userdefined object class implement IComparable so it
exposes some means that users of your class (like ArrayList) might be
able to compare your object.

2) have your userdefined object class override Equals (again for the
same reason).

================
Clay Burch
Syncfusion, Inc.
 
Here is my code...

Public Class cTestClass
Implements IComparable

#Region "Attributes"
Private _fName As String
Private _lName As String
#End Region

#Region "New"
Public Sub New(ByVal Fname As String, ByVal Lname As String)
_fName = Fname
_lName = Lname
End Sub
#End Region

#Region "Methods"
Public Overrides Function ToString() As String
Return _fName
End Function

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

If TypeOf obj Is cTestClass Then
Dim test As cTestClass = CType(obj, cTestClass)

Return Me._fName.CompareTo(test._fName)
End If

Throw New ArgumentException("object is not a cTestClass")
End Function

#End Region

####################################################################


Public Class Form1
Inherits System.Windows.Forms.Form
Private MyArray As New ArrayList
Private MyTest As cTestClass

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

MyTest = New cTestClass("Kym", "Tester")
MyArray.Add(MyTest)

MyTest = New cTestClass("Linda", "Tester")
MyArray.Add(MyTest)
MyTest = New cTestClass("Kym", "Tester")

Debug.WriteLine(MyTest.ToString)

If MyArray.Contains(MyTest) Then
'This does not execute, I would expect this to execute as the
arraylist contains this object, Whats going on here?
Debug.WriteLine("Object exists")
Else
Debug.WriteLine("Object does not exists")
End If

If MyArray.Contains(MyTest.ToString) Then
'This does not execute.
Debug.WriteLine("Object exists")
Else
Debug.WriteLine("Object does not exists")
End If

End Sub

End Class
 
Try this change to your cTestClass code.

1) add an Equals override

Public Overrides Function Equals(ByVal obj As Object) As Boolean
Return CompareTo(obj) = 0
End Function


====================
Clay Burch
Syncfusion, Inc.
 
Kym said:
Here is my code...
[...]

In Class cTestClass, Override function Equals because that's what
arraylist.contains calls to compare items.


Armin
 
I have tried that and get the following...
'function 'Equals' shadows an overloadable member declared in the base class
'Object'. If you want to overload the base method, this method must be
declared 'Overloads'.'

Have tried using 'OverLoads' as well but this does not work either.
Any other ideas how this can be done?

Kym
 
Kym said:
I have tried that and get the following...
'function 'Equals' shadows an overloadable member declared in the
base class 'Object'. If you want to overload the base method, this
method must be declared 'Overloads'.'

Have tried using 'OverLoads' as well but this does not work either.
Any other ideas how this can be done?

Kym

Have you put a breakpoint in your Equals function to see if it's called as
soon when you call the Contains method? Only has to do

Return Me._fName.Equals(test._fName)


Armin
 
The point here is what provides the point of distinction between objects of
the same type? At face value it is the combination of _fName/_lName.

While the first and third objects that you are dealing with may appear to be
the same object, they are, in fact, not.

Each time you execute:

MyTest = New cTestClass("Kym", "Tester")

you are creating a new instance cTestClass that has no connection with any
other instance of cTestClass except that they are of the same type.

When you execute:

If MyArray.Contains(MyTest)

then you are asking if the ArrayList contains that specfic instance of
cTestClass, which, of course, it does not. The ArrayList cannot possibly
contain an object that has just been created and not yet added.

What you need here is a method for determining if an object is present in
the ArrayList that matches on the point of difference between objects of
that type. Something like:

Function Contains(ByVal o As cTestClass)

For Each _o As cTestClass in MyArray
If _o.FName = o.FName AndAlso _o.LName = o.LName The Return True
Next

Return False

End Function

You will also, of course, need to add properties to cTestClass to expose
FName and LName.
 
Stephany Young said:
When you execute:

If MyArray.Contains(MyTest)

then you are asking if the ArrayList contains that specfic instance
of cTestClass, which, of course, it does not. The ArrayList cannot
possibly contain an object that has just been created and not yet
added.


I thought, Contains does not compare references. Doesn't it call the
Equals method for all objcts in the list? Therefore I think overriding the
Equals method would be sufficient.


Armin
 
Kym said:
I have tried that and get the following...
'function 'Equals' shadows an overloadable member declared in the
base class 'Object'. If you want to overload the base method, this
method must be declared 'Overloads'.'

Have tried using 'OverLoads' as well but this does not work either.
Any other ideas how this can be done?

You must /override/ it, not overload:

Public Overrides Function Equals(ByVal obj As Object) As Boolean
Return Me._fName.Equals(obj._fName)
End Function


Armin
 
Yes. You are correct for a derived class that overrides Equals.

If Equals is not overriden in the the derived class then the Equals method
of Object is called and that only suppourts reference equality.
 
I was getting an error when I tried using...
Public Overrides Function Equals(ByVal obj As Object) As Boolean
Return CompareTo(obj) = 0
End Function

It works when I use...
Public Overloads Overrides Function Equals(ByVal obj As Object) As
Boolean
Return CompareTo(obj) = 0
End Function

Thanks to all for the help
 
Kym said:
I was getting an error when I tried using...
Public Overrides Function Equals(ByVal obj As Object) As Boolean Return
CompareTo(obj) = 0
End Function

It works when I use...
Public Overloads Overrides Function Equals(ByVal obj As Object)
As Boolean
Return CompareTo(obj) = 0
End Function

Thanks to all for the help


You're right. I used VB 2005 where you can leave out the "overloads", it's
only (unneccessarily) necessary in VB 2003.


Armin
 
Back
Top