So now, we’ve covered a lot with regards to Lists, Sets and
Maps. However, so far, we’ve only used Java’s inbuilt datatypes as elements of
the collections. What if we want to use our own custom objects as keys to maps
or as elements in sets? How do we do it?
Well, let us first create a class
Bird. We will give each bird a tagNumber to identify it and a name. We will
also create a constructor for the class that allows us to initialize the two
member variables of the class as we create a new Bird object. Finally, we will
give Bird a toString() method so that we can get some nice output when we use
System.out.println() on an object of the class.
public class Bird {
private int
tagNumber;
private
String name;
public
Bird(int tagNumber, String name) {
this.tagNumber
= tagNumber;
this.name
= name;
}
public
String toString () {
return
“tagNumber is: ” + tagNumber + “ name is: ” + name;
}
}
Custom Objects with Sets
So let’s create a set containing items of the class Bird and
add some items into it:
Set<Bird> birds = new HashSet<Bird>();
birds.add(new Bird(1, “hawk”));
birds.add(new Bird(5, “pigeon”));
birds.add(new Bird(7, “owl”));
birds.add(new Bird(1, “hawk”));
Now, notice that we have two elements that have the same
tagNumber and name. What this implies is that the two objects are identical and
based on how sets are supposed to behave, there should be only one item with
the tagNumber 1 and the name “hawk”.
Figure 1: When you add custom objects to sets, Java by default does not know if they are equal
To get around this, we need to implement the equals() and hashCode() methods. The easiest way is to get your IDE to generate the two methods for you. In Eclipse, which I use, you right-click within the class file and go to Source, then click in “Generate hashCode() and toString(). Select the fields needed to determine the equality.
For example, if you feel that two Bird objects are equal if they have the same tagNumber regardless of their name, then only select the tagNumber. if you feel that two Bird objects are equal if they have the same name regardless of their tagNumber, then only select the tagNumber. if you feel that two Bird objects are equal if they have the same tagNumber and name, then select the two fields.
Figure 2: Now Java shows unique objects after overriding the equals() and hashCode() methods
Now, if you run the program again, you see that only one
“hawk” object is listed, which is as it should be. The reason why this didn’t
work in the first place is because Java doesn’t go into your objects to look
what equality really means. You have to tell Java the criteria needed to
conclude that two objects are equal.
Custom Objects with Maps
So let’s create a set containing items of the class Bird and
add some items into it:
Map<Integer, Bird> birds = new
HashMap<Integer, Bird>();
birds.put(2, new Bird(1, "hawk"));
birds.put(6, new Bird(5,
"pigeon"));
birds.put(9, new Bird(7, "owl"));
birds.put(2, new Bird(1, "hawk"));
Now, notice that we have two elements that have the same
tagNumber and name. What this implies is that the two objects are identical and
based on how sets are supposed to behave, there should be only one item with
the tagNumber 1 and the name “hawk”.
But if we try to output the set birds, Java will only output
one of the objects with the same key and ignore the first one.
for (Integer key: birds.keySet()) {
System.out.println(key
+ “: ” + birds.get(key));
}Figure 3: After overriding the hashCode() and equals() methods, Java only displays objects with unique keys.
That’s it for this tutorial. In the next tutorial, we are
going to look at the concept of natural order in collections framework.
If you have any questions or comments, please leave them in
the comments section below and I will make sure to address them.
Until next time, take care.
No comments:
Post a Comment