Java Reference
In-Depth Information
30.29
Segment 16.1 of Chapter 16 noted that objects in a sorted list must be
Comparable
—that is, they must
have a
compareTo
method. In this case, we also want the objects to be
Cloneable
. Segment 30.20
defined an interface
Copyable
that declares a public method
clone
. Using that interface, let's create
another one:
public interface
ComparableAndCopyable<T>
extends
Comparable<T>, Copyable
{
}
// end ComparableAndCopyable
This interface will enable us to bound the generic type of the objects we place into the sorted list, as
the next segment will show.
A class that implements
ComparableAndCopyable
must define the methods
compareTo
and
clone
. For example, the class
Name
mentioned in Segment 30.15 could begin as follows:
public class
Name
implements
ComparableAndCopyable<Name>
Name
's method
clone
is given in Segment 30.15, and you wrote
compareTo
when you answered
Question 8 in Appendix D.
30.30
Since we want the sorted list to contain only objects that are both
Comparable
and
Copyable
, we can
begin the definition of a class
SortedList
as follows:
public class
SortedList<T
extends
ComparableAndCopyable<?
super
T>>
We introduced this notation in Segments 8.1 and 8.2 of Chapter 8. The class that
T
represents must
implement the interface
ComparableAndCopyable
. The notation
?
super
T
, which means any superclass
of
T
, affects the interface
Comparable
—as you can see by looking at
ComparableAndCopyable
—and
hence the method
compareTo
.
We can revise our interface for a sorted list by beginning it as follows:
public interface
SortedListInterface
<T
extends
ComparableAndCopyable<?
super
T>>
and then use it in the definition of
SortedList
:
public class
SortedList<T
extends
ComparableAndCopyable<?
super
T>>
implements
SortedListInterface<T>
30.31
With these logistics out of the way, we propose the following changes to the implementation of the
ADT sorted list. You can apply these changes to the implementations discussed in Chapters 16
and 17:
•
In
add
, place a clone of the desired entry into the sorted list instead of the entry itself. That is,
place
newEntry.clone()
into the list instead of
newEntry
. Thus, the body of the method
could begin with
Node newNode =
new
Node((T)newEntry.clone());
Since clone returns an
Object
, the cast to the generic type
T
is necessary.
•
In
getEntry
, return a clone of the desired entry instead of the entry itself. For example, you
could return
(T)result.clone()
instead of
result
.
Let's examine these changes more closely. Suppose that a client has a reference,
newEntry
, to
an object, and it adds the object to a collection. The collection clones the object and adds the clone
instead of the original object, as Figure 30-11 illustrates. The client has no reference to the collec-
tion's data. If the client modifies the object that
newEntry
references, the collection is not changed.
What if
getEntry
did not return a clone of the desired entry but instead returned a reference to
the desired entry in the collection? As Figure 30-12 illustrates, the client would be able to change