tags:

views:

36

answers:

4
 Dim dct As New Dictionary(Of ArrayList, ArrayList)

 ' Populate Dictionary 
 dct.Add(New ArrayList({"Dot", "0"}), New ArrayList({20, 30, 40,> 50}))
 dct.Add(New ArrayList({"Dot", "1"}), New ArrayList({120, 130, 140,> 150}))

 ' Search in dictionary 
 Dim al As New ArrayList({"Dot", "2"}) 
 If dct.ContainsKey(al) Then ' does not work****   
     MessageBox.Show("Found: " &  al(0).ToString) 
 End If
A: 

You create a new ArrayList and you do not add it to your dictionary. Why do you expect it to be found in the dictionary?

You need to add the new ArrayList to the dictionary before it can be found in it.

You have two different ArrayList objects that have the same content. They are however still different objects, one in the dictionary and another one that is not in the dictionary.

Oded
A: 

Thats because it performs a reference comparison whereas you are expecting it to a value comparison.

Both the arrayList are same in the content but it doesn't point to same instance & hence, it fails.

EDIT: Also, why are you expecting this (al) to be found, when it is not present in the dictionary?

shahkalpesh
A: 

(al) entry is in the dictionary, however I did not put it here to keep the code short. How can we point to the same instance?

Zahid
+2  A: 

For a dictionary to work properly, the keys must be equal if they have the same value. Your dictionary uses the ArrayList.Equals() method to compare array lists. That method does not do what you need it to do, it only returns True if the array lists are the same object.

You'll need to use a dictionary constructor that lets you pass a comparer. Make it look like this:

    Dim dct As New Dictionary(Of ArrayList, ArrayList)(new MyComparer())

Where the MyComparer class is a comparer that implements IEqualityComparer(Of ArrayList). A possible implementation could be this one:

Class MyComparer
    Implements IEqualityComparer(Of ArrayList)
    Public Function Equals1(ByVal x As System.Collections.ArrayList, ByVal y As System.Collections.ArrayList) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of System.Collections.ArrayList).Equals
        If x.Count <> y.Count Then Return False
        For ix As Integer = 0 To x.Count - 1
            If Not x(ix).Equals(y(ix)) Then Return False
        Next
        Return True
    End Function

    Public Function GetHashCode1(ByVal obj As System.Collections.ArrayList) As Integer Implements System.Collections.Generic.IEqualityComparer(Of System.Collections.ArrayList).GetHashCode
        Return obj.Count.GetHashCode
    End Function
End Class
Hans Passant
I agree with the approach. The methods should handle null parameters though, and the equals short-circuit on cases where it actually is the same object, and ReferenceEquals returns true. The GetHashCode could be better by using an approach similar to that used in the implementation in the string class.
Jon Hanna
No, having nulls in the dictionary would be a bug, don't hide the bug. GetHashCode must be cheap, hard to do with an ArrayList.
Hans Passant