Java Reference
In-Depth Information
1 public static void main( String [] args )
2 {
3 Set<String> s = new HashSet<String>( );
4 s.add( "joe" );
5 s.add( "bob" );
6 s.add( "hal" );
7 printCollection( s ); // Figure 6.11
8
figure 6.32
An illustration of the
HashSet , where items
are output in some
order
}
This is done by having each element implement a special hashCode method; we
describe this method later in this subsection.
Figure 6.32 illustrates the use of the HashSet . It is guaranteed that if we
iterate through the entire HashSet , we will see each item once, but the order
that the items are visited is unknown. It is almost certain that the order will not
be the same as the order of insertion, nor will it be any kind of sorted order.
Like all Set s, the HashSet does not allow duplicates. Two items are consid-
ered equal if the equals method says so. Thus, any object that is inserted into
the HashSet must have a properly overridden equals method.
Recall that in Section 4.9, we discussed that it is essential that equals is
overridden (by providing a new version that takes an Object as parameter)
rather than overloaded.
implementing equals and hashCode
Overriding equals is very tricky when inheritance is involved. The contract for
equals states that if p and q are not null , p.equals(q) should return the same
value as q.equals(p) . This does not occur in Figure 6.33. In that example,
clearly b.equals(c) returns true , as expected. a.equals(b) also returns true ,
because BaseClass 's equals method is used, and that only compares the x com-
ponents. However, b.equals(a) returns false , because DerivedClass 's equals
method is used, and the instanceof test will fail ( a is not an instance of
DerivedClass ) at line 29.
equals must be
symmetric; this is
tricky when inheri-
tance is involved.
There are two standard solutions to this problem. One is to make the
equals method final in BaseClass . This avoids the problem of conflicting
equals . The other solution is to strengthen the equals test to require that the
types are identical, and not simply compatible, since the one-way compati-
bility is what breaks equals . In this example, a BaseClass and DerivedClass
object would never be declared equal. Figure 6.34 shows a correct imple-
mentation. Line 8 contains the idiomatic test. getClass returns a special
object of type Class (note the capital C ) that represents information about
any object's class. getClass is a final method in the Object class. If when
invoked on two different objects it returns the same Class instance, then the
two objects have identical types.
Solution 1 is to not
override equals
below the base
class. Solution 2 is
to require identi-
cally typed objects
using getClass .
 
Search WWH ::




Custom Search