Given the following class and code someone new to B4A might expect a different result to the one which is actually produced by the following code and class definition.
The Pleistocene_Mammal class
The Activity Code
The code adds 4 Pleistocene_Mammal objects to the Mammals List so our list is
The log output will show:
This because the IndexOf method is using a method called equals that is a method common to all Java classes.
IndexOf will call the equals method of each object in the list to compare it to the FindMammal object.
By default the equals method does something similar to this in B4A
Using inline Java we can override the default behavior of the equals method in the Pleistocene_Mammal class to do something more useful.
To start I am going to use an additional Jar file which makes it very easy to build custom equals methods. It's part of the Apache commons Java components and the JAR file can be downloaded here.
So the start of my Activity code now looks like this:
I now need to override the equals method in the Pleistocene_Mammal class using inline Java..
Pleistocene_Mammal class
Taking the Java code in manageable chunks.
This imports the class EqualsBuilder which I am using to compare one object with the other.
This is a compiler directive telling Java that I am overriding an inherited method.
Declares the method equals which returns a boolean type and that it expects an Object as it's parameter type.
Test if the passed Object obj class type is pleistocene_mammal. If it isn't return false. If the class types match then return true if object is the same instance.
The first thing to note here is that when B4A generates Java code it makes all class names lower case. It also makes all the properties lowercase and prefixes them with an underscore. You can check what happens to your properties by looking in your projects objects\src folder.
So the Species property becomes _species and the Family property becomes _family.
The first line casts the passed object obj to the to an instance of the pleistocene_mammal class called compare.
The second line creates an new EqulaBuilder object called z which we are going to use to compare the two objects.
This code calls EqualsBuilder append method to add the properties from each object to be compared. This may may not be all the properties in your class as some of them may not matter.
Finally the isEquals method of the EqualsBuilder object is called to compare the properties. If they are equal true is returned otherwise false is returned.
I have attached the sample code project and when you run it you should find the the log shows:
In Part 2 I will explain how to extend this to cover more complex cases where you have a hierarchy of contained objects.
The Pleistocene_Mammal class
B4X:
'Class module
Sub Class_Globals
Dim Species As String
Dim Family As String
End Sub
Public Sub Initialize(mSpecies As String, mFamily As String)
Species = mSpecies
Family = mFamily
End Sub
The Activity Code
B4X:
Sub Process_Globals
Dim Mammals As List
End Sub
Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
Mammals.Initialize
Dim Mammoth As Pleistocene_Mammal
Dim Lion As Pleistocene_Mammal
Dim Smilodon As Pleistocene_Mammal
Dim Rhino As Pleistocene_Mammal
Mammoth.Initialize("Wooly Mammoth","Elephant")
Lion.Initialize("Cave Lion","Cat")
Smilodon.Initialize("Smilodon","Cat")
Rhino.Initialize("Wooly Rhino","Rhino")
Mammals.Add(Mammoth)
Mammals.Add(Lion)
Mammals.Add(Smilodon)
Mammals.Add(Rhino)
Dim FindMammal As Pleistocene_Mammal
FindMammal.Initialize("Wooly Mammoth", "Elephant")
If Mammals.IndexOf(FindMammal) >= 0 Then
Log("Wooly Mammoth Found! :-)")
Else
Log("No Wooly Mammoths :-(")
End If
End Sub
The code adds 4 Pleistocene_Mammal objects to the Mammals List so our list is
- Wooly Mammoth
- Cave Lion
- Smilodon
- Wooly Rhino
The log output will show:
B4X:
"No Wooly Mammoths :-("
IndexOf will call the equals method of each object in the list to compare it to the FindMammal object.
By default the equals method does something similar to this in B4A
B4X:
Sub Equals(o As Object) As Boolean)
Return o = Me
End Sub
Using inline Java we can override the default behavior of the equals method in the Pleistocene_Mammal class to do something more useful.
To start I am going to use an additional Jar file which makes it very easy to build custom equals methods. It's part of the Apache commons Java components and the JAR file can be downloaded here.
So the start of my Activity code now looks like this:
B4X:
#AdditionalJar: commons-lang3-3.3.2
Sub Process_Globals
Dim Mammals As List
End Sub
Sub Globals
End Sub
I now need to override the equals method in the Pleistocene_Mammal class using inline Java..
Pleistocene_Mammal class
B4X:
Sub Class_Globals
Dim Species As String
Dim Family As String
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(mSpecies As String, mFamily As String)
Species = mSpecies
Family = mFamily
End Sub
#If Java
import org.apache.commons.lang3.builder.EqualsBuilder;
@Override
public boolean equals(Object obj) {
if (!(obj instanceof pleistocene_mammal))
return false;
if (obj == this)
return true;
[code
}
#End If
Taking the Java code in manageable chunks.
B4X:
import org.apache.commons.lang3.builder.EqualsBuilder;
This imports the class EqualsBuilder which I am using to compare one object with the other.
B4X:
@Override
This is a compiler directive telling Java that I am overriding an inherited method.
B4X:
public boolean equals(Object obj) {
Declares the method equals which returns a boolean type and that it expects an Object as it's parameter type.
B4X:
if (!(obj instanceof pleistocene_mammal))
return false;
if (obj == this)
return true;
Test if the passed Object obj class type is pleistocene_mammal. If it isn't return false. If the class types match then return true if object is the same instance.
B4X:
pleistocene_mammal compare = (pleistocene_mammal) obj;
EqualsBuilder z = new EqualsBuilder();
The first thing to note here is that when B4A generates Java code it makes all class names lower case. It also makes all the properties lowercase and prefixes them with an underscore. You can check what happens to your properties by looking in your projects objects\src folder.
So the Species property becomes _species and the Family property becomes _family.
The first line casts the passed object obj to the to an instance of the pleistocene_mammal class called compare.
The second line creates an new EqulaBuilder object called z which we are going to use to compare the two objects.
B4X:
z.append(this._species, compare._species);
z.append(this._family, compare._family);
This code calls EqualsBuilder append method to add the properties from each object to be compared. This may may not be all the properties in your class as some of them may not matter.
B4X:
if (z.isEquals()) {
return true;
} else {
return false;
}
}
Finally the isEquals method of the EqualsBuilder object is called to compare the properties. If they are equal true is returned otherwise false is returned.
I have attached the sample code project and when you run it you should find the the log shows:
B4X:
"Wooly Mammoth Found! :-)"
In Part 2 I will explain how to extend this to cover more complex cases where you have a hierarchy of contained objects.