Comparable and ComparatorNuts and boltsComparing our own objectsOutline of a Student classConstructor for StudentThe main method, version 1Using the TreeSetImplementing ComparableAn improved methodUsing a separate ComparatorOutline of StudentComparatorThe compare methodThe someComparator.equals methodThe main methodWhen to use eachSorting differentlyThe EndComparable and ComparatorNuts and Bolts2Nuts and boltsFour methods underlie many of Java’s important Collection types: equals, compare and compareTo, and hashCodeTo put your own objects into a Collection, you need to ensure that these methods are defined properlyAny collection with some sort of membership test uses equals (which, in many cases, defaults to ==)Any collection that depends on sorting requires larger/equal/smaller comparisons (compare or compareTo)Any collection that depends on hashing requires both equality testing and hash codes (equals and hashCode)Any time you implement hashCode, you must also implement equalsSome of Java’s classes, such as String, already define all of these properly for youFor your own objects, you have to do it yourself3Comparing our own objectsThe Object class provides public boolean equals(Object obj) and public int hashCode() methodsFor objects that we define, the inherited equals and hashCode methods use the object’s address in memoryWe can override these methodsIf we override hashCode, we must override equalsThe Object class does not provide any methods for “less” or “greater”—however,There is a Comparable interface in java.langThere is a Comparator interface in java.util4Outline of a Student classpublic class Student implements Comparable {public Student(String name, int score) {...}public int compareTo(Object o)throws ClassCastException {...}public static void main(String args[]) {...}}5Constructor for StudentThis is the same for both methods—nothing new herepublic Student(String name, int score) {this.name = name;this.score = score;}We will be sorting students according to their scoreThis example will use sets, but that’s irrelevant—comparisons happen between two objects, whatever kind of collection they may or may not be in6The main method, version 1 public static void main(String args[]) { TreeSet set = new TreeSet(); set.add(new Student("Ann", 87)); set.add(new Student("Bob", 83)); set.add(new Student("Cat", 99)); set.add(new Student("Dan", 25)); set.add(new Student("Eve", 76)); Iterator iter = set.iterator(); while (iter.hasNext()) { Student s = (Student)iter.next(); System.out.println(s.name + " " + s.score); }}7Using the TreeSetIn the main method we have the line TreeSet set = new TreeSet();Later we use an iterator to print out the values in order, and get the following result: Dan 25Eve 76Bob 83Ann 87Cat 99How did the iterator know that it should sort Students by score, rather than, say, by name?8Implementing Comparablepublic class Student implements ComparableThis means it must implement the methodpublic int compareTo(Object o)Notice that the parameter is an ObjectIn order to implement this interface, our parameter must also be an Object, even if that’s not what we wantpublic int compareTo(Object o) throws ClassCastException { if (o instanceof Student) return score - ((Student)o).score; else throw new ClassCastException("Not a Student!");}A ClassCastException should be thrown if we are given a non-Student parameter9An improved methodSince casting an arbitrary Object to a Student may throw a classCastException for us, we don’t need to throw it explicitly:public int compareTo(Object o) throws ClassCastException { return score - ((Student)o).score;}Moreover, since classCastException is a subclass of RuntimeException, we don’t even need to declare that we might throw one:public int compareTo(Object o) { return score - ((Student)o).score;}10Using a separate ComparatorIn the program we just finished, Student implemented Comparable Therefore, it had a compareTo methodWe could sort students only by their scoreIf we wanted to sort students another way, such as by name, we are out of luckNow we will put the comparison method in a separate class that implements Comparator instead of ComparableThis is more flexible (you can use a different Comparator to sort Students by name or by score), but it’s also clumsierComparator is in java.util, not java.langComparable requires a definition of compareTo but Comparator requires a definition of compare Comparator also (sort of) requires equals11Outline of StudentComparator import java.util.*; public class StudentComparator implements Comparator { public int compare(Object o1, Object o2) {...} public boolean equals(Object o1) {...}}Note: When we are using this Comparator, we don’t need the compareTo method in the Student class12The compare method public int compare(Object o1, Object o2) { return ((Student)o1).score - ((Student)o2).score;}This differs from compareTo(Object o) in Comparable in these ways:The name is differentIt takes both objects as parameters, not just oneWe have to check the type of both objectsBoth objects have to be cast to Student13The so meComparator.equals methodIgnore this method!This method is not used to compare two Students—it is used to compare two ComparatorsEven though it’s part of the Comparator interface, you don’t actually need to override itImplementing an interface requires you to have a definition for every method in the interface--so how can this be an exception?Because you do have a definition, inherited from Object !In fact, it’s always safe to ignore this methodThe purpose is efficiency—you can replace one Comparator with an equal but faster one14The main methodThe main method is just like before, except that instead of TreeSet set = new TreeSet();We have Comparator comp = new StudentComparator(); TreeSet set = new TreeSet(comp);15When to use eachThe Comparable interface is simpler and less workYour class implements ComparableProvide a public int compareTo(Object o) methodUse no argument in your TreeSet or TreeMap constructorYou will use the same comparison method every timeThe Comparator interface is more flexible but slightly more workCreate as many different classes that implement Comparator
View Full Document