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