Some time ago I stumbled upon a problem with the ArrayList class. I was writing an application to have my documents from various network locations synchronized to a single folder. I used ArrayLists to hold the files in the various folders and compared the entries to see what is different. The problem was the an entry "my Excel File.xls" would be seen different than "My excel file.XLS", i.e. the arraylist is case sensitive when comparing string values.
I solved this by writing a class derived from the Arraylist class, adding case insensitive functionality. Here's the code:
Construct a new instance:
Code:
Public Class CaseInsensitiveArrayList
Inherits ArrayList
Public Sub New()
MyBase.New()
End Sub
Define a function to search the arraylist for the provided value, ignoring the character casing:
Code:
Private Function SearchEntry(ByVal value As Object) As String
Dim SearchValue As String = Convert.ToString(value).ToLower
For Each Entry As String In Me
If Entry.ToLower = SearchValue Then
Return Entry
End If
Next
Return Nothing
End Function
The function first converts the given value to a string, and sets all casing to lowercase. Next it loops through the values in the arraylist (Me) and compares the given value to the current value in the list in lowercase. If the values match, the entry is returned, retaining it's original casing. If the value was not found, Nothing is returned.
Next I had to override all methods that use a given value to perform an action. I started with the Contains function:
Code:
Public Overrides Function Contains(ByVal value As Object) As Boolean
If SearchEntry(value) Is Nothing Then
Return False
Else
Return True
End If
End Function
This code is straightforward; if the given value matched an entry in the arraylist then this function returns True, otherwise it return False.
In the same manner the methods IndexOf and LastIndexOf and their overloaded versions have to be overridden:
Code:
Public Overloads Overrides Function IndexOf(ByVal value As Object) As Integer
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then
Return -1
Else
Return MyBase.IndexOf(Entry)
End If
End Function
Public Overloads Overrides Function IndexOf(ByVal value As Object, ByVal startIndex As Integer) As Integer
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then
Return -1
Else
Return MyBase.IndexOf(Entry, startIndex)
End If
End Function
Public Overloads Overrides Function IndexOf(ByVal value As Object, ByVal startIndex As Integer, ByVal count As Integer) As Integer
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then
Return -1
Else
Return MyBase.IndexOf(Entry, startIndex, count)
End If
End Function
Public Overloads Overrides Function LastIndexOf(ByVal value As Object) As Integer
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then
Return -1
Else
Return MyBase.LastIndexOf(Entry)
End If
End Function
Public Overloads Overrides Function LastIndexOf(ByVal value As Object, ByVal startIndex As Integer) As Integer
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then
Return -1
Else
Return MyBase.LastIndexOf(Entry, startIndex)
End If
End Function
Public Overloads Overrides Function LastIndexOf(ByVal value As Object, ByVal startIndex As Integer, ByVal count As Integer) As Integer
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then
Return -1
Else
Return MyBase.LastIndexOf(Entry, startIndex, count)
End If
End Function
As you can see, the functions first check to see wether the value exists in the arraylist, disregarding the character casing, and then uses it's base to perform the relevant method on the entry.
Last I had to override the Remove method to correctly allow an entry to be removed:
Code:
Public Overrides Sub Remove(ByVal value As Object)
Dim Entry As String = SearchEntry(value)
If Entry Is Nothing Then Return
MyBase.Remove(Entry)
End Sub
End Class
This overridden method also uses it's base to handle the removing itself on the correct entry.