Comparable and Comparator Interfaces

advertisement
Comparable and
Comparator Interfaces
Ben Rodes
Disclaimer
Interfaces

Problem: You don’t know what an
interface is yet!


Seems problematic
So what is an interface?


Its not a class!
A group of related methods with no bodies (no
definition, just method signatures)
Interfaces
A class may implement any number of
interfaces.
 To implement an interface is a contract.



The implementer must define the interface
functions!
Why do this?


We can use objects of an interface type,
without knowing their actual instance type.
Let’s look at an example.
Interfaces
public interface TimeKeeper
{
public Time getTime();
public void setTime(Time);
….
}
Interfaces
public class Watch implements TimeKeeper
{
//Whatever fields go here
//Constructor, methods ….
public Time getTime()
{
//Define this function
}
}
public void setTime()
{
//Define this function
}
Interfaces
You can think of Watch in these ways:




You can treat a Watch object as a TimeKeeper
A Watch object can do “TimeKeeper things”
A Watch object can be used anywhere a
TimeKeeper is legal to use
A Watch object has more than one type


It’s a Watch (defined by the class Watch)
It’s a TimeKeeper (defined by the interface)
Interfaces

Okay but why?


Hold on, I am getting there!
Let’s pretend you want to write some
generic function to work on TimeKeepers
Interfaces
public Time getAVGClkDiff(ArrayList<TimeKeeper> clocks)
{
//Loop over each element in clocks
//for each element e
e.getTime(); //Get the time, store it, take an average
}

This may not be the exactly right syntax, but the right idea
Interfaces


Okay, dumb example, but …
 We don’t care what the actual time keepers are
 Because an interface is a contract, we know a
TimeKeeper has a getTime function, and we can treat
each element as a TimeKeeper, rather than whatever
instance it actually is.
Similar idea to inheritance, but is subtly different.
 Interfaces do not show inheritance.
 Relationships are maintained among diverse objects.
 More to come later.
The Comparable Interface

Comparable is an interface


Contains only one method


Defined in the Java API
compareTo(SomeObject o2)
There are functions in the Java API you
can use to do useful things if your objects
implement this interface.
Check out the Collections class

Class Collections
 utility methods for doing operations on Collections

See MSD textbook, Section 9.5, pp. 666f
Methods (static, mostly for Lists)
 search a list for an item: binarySearch()
 sort(), max(), min() -- uses compareTo() or Comparator
object
 reverse(), fill(), shuffle(), copy(), replaceAll()
 List list2 = Collections.unmodifiableList(list1); // p. 668


Note very similar Arrays class
Collections Sort






Accepts a List of comparable objects.
How might a sort() or any other method use this?
Imagine:
 Perhaps items stored as a list of Objects:
List theList …;
Inside a loop, code might look like this:
Comparable item1 = (Comparable) theList.get(i);
Comparable item2 = (Comparable) theList.get(j);
int cmpResult = item1.compareTo(item2);
Such code will work when the list stores any class that implements
Comparable!
But, what happens if list-elements are of different classes (still
Comparable, but different)? compareTo() fails!
Lets look at an example!
Example: Writing compareTo()
Imagine something like an entry in a phonebook
 Order by last name, first name, then number
int compareTo(PhoneBookEntry item2 ) {
int retVal= last.compareTo(item2.last);
if ( retVal != 0 ) return retVal;
retVal = first.compareTo(item2.first);
if ( retVal != 0 ) return retVal;
retVal = phNum - item2.phNum;
return retVal;
}

Comparable Problems



Lack of flexibility
Just one way to compare is possible,
because there’s just one compareTo method per
class
Possible solutions:

Separate functions: sortByName(), sortByNum(),…


We can’t predict in advance how you’ll want to sort!
Pass a parameter to indicate control:
sort(theList, “byName”) or sort(theList, “byNum”);


Ugh. Same problem as before
And the internals of sort() will grow to become very ugly
Function Objects


We need to somehow pass “how to execute” information as
a parameter to sort()
 We pass objects as parameters
 Can we pass a method/operation as an object?
Many languages support this, but in different ways:
 C and C++ – pointers to functions
 C# – delegates
 Java – “function objects” that
 implement a specified interface, and
 the one method in that interface does the needed
work
Function Objects in Java



Idea: encapsulate a function inside a class
Note: not our usual idea of a class
 State? (None.)
 Identity? (Just need one instance.)
 Represents an entity? (Nope! Just a place to stash a function
so it can be passed as a parameter.)
Warning / caveat!
 This idea is contrary to many OO principles, but…
 Useful if done in limited circumstances
 Use it when the libraries make it available
 Not often part of your own class-design
 But use it in libraries when it’s part of the framework
Example: Comparator objects




We want to pass a function-object to a method:
 Collections.sort(someList, function-object-goes-here);
 But what type should this object be?
 Use an Interface:
 Interface name can be used as a type in the parameter list
 Interface defines the method name itself!
Java’s Comparator interface:
int compare( Object o1, Object o2);
 Notes: not compareTo()! Takes two parameters!
Define a class for each kind of comparison you want. E.g.
Classes: CmpStudentByGpa, CmpStudentByGpaDesc
Classes: CmpDogByName, CmpDogByBreed
Example?
Writing a Comparator Class





Example on following slides like one from MSD text, p. 646647
 We have a Dog class with name, breed and gender
But see simpler example in Java on website
 list of Student objects
 sort by name, gpa
 Also sort in descending order too
Look at testSorting1() in TestDriver class
Look at compareTo() in Student
Look at use of comparator classes
Download