Using Person Objects In A Collection


Implementing The java.lang.Comparable Interface

If objects of a particular class are to be inserted into a sorted collection then there must be a way for the collection insertion mechanism to determine if one object is greater-than, less-than, or equal to another object of the same type. To participate in such a comparison an object must implement the Comparable interface. The Comparable interface has one method: compareTo(), which must be implemented to communicate this natural ordering.

An class’s natural ordering is completely at the mercy of the design. Sometimes, a class’s natural ordering is immediately evident. Take the Integer class for example. Given the values 1, 3, and 5, it’s easy to see their natural ordering. But what, exactly, would constitute a natural ordering for the Person class? If we select the calculated attribute age then Person objects inserted into a collection will be sorted according to how old they are. (either ascending or descending) If we order them according to their last_name then they will be inserted into the collection alphabetically by last name.

The one rule that the Java API documentation recommends you follow when implementing the Comparable.compareTo() method is that it should behave consistently with the equals() method. (It is a recommendation — not a requirement.) This means that if there are two logically equal Person references p1 and p2, then (p1.compareTo(p2) == 0) has the same value as p1.equals(p2).

Let’s see how this might be done in the Person class. Example 23.9 gives the code for the Person.compareTo() method.

Example 23.9: Person.compareTo()

image from book
 1     public int compareTo(Object o){ 2         return this.toString().compareTo(o.toString()); 3       }
image from book

This was too easy! As it turns out, the String class implements Comparable. Since Person overrides toString() it can be used to get string representations of each Person object. But since the Person.toString() method includes both name and birthday information, does the ordering make sense? One thing is certain, this implementation behaves consistently with equals()!

Example 23.10 gives the code for a modified version of MainTestApp that tests the Person.compareTo() method. Figure 23-9 shows the results of running this program.

Example 23.10: MainTestApp.java (mod 3)

image from book
 1     public class MainTestApp { 2       public static void main(String[] args){ 3         Person p1 = new Person("Rick", "W", "Miller", 1963, 5, 6, Person.MALE); 4         Person p2 = new Person("Rick", "W", "Miller", 1963, 5, 6, Person.MALE); 5         Person p3 = new Person("Rick", "W", "Miller", 1963, 5, 6, Person.MALE); 6         Person p4 = new Person("Steve", "J", "Jones", 1932, 9, 20, Person.MALE); 7 8         System.out.println("P1: " + p1.toString()); 9         System.out.println("P2: " + p2.toString()); 10        System.out.println("P3: " + p3.toString()); 11        System.out.println("P4: " + p4.toString()); 12 13        System.out.println(p1.equals(p1));  // reflexive - should be true 14        System.out.println(p1.equals(p2) && p2.equals(p1)); // symmetric - should be true 15        System.out.println(p1.equals(p2) && p2.equals(p3) && p1.equals(p3)); // transitive - should be true 16        System.out.println(p1.equals(p2)); // consistent - should be true every time this app executes 17        System.out.println(p1.equals(p4)); // consistent - should be false every time this app executes 18        System.out.println(p1.equals(null)); // should always return false 19 20        System.out.println(); 21        System.out.println(p1.hashCode()); 22        System.out.println(p2.hashCode()); 23        System.out.println(p3.hashCode()); 24        System.out.println(p4.hashCode()); 25        System.out.println(); 26 27        try{ 28          Person p5 = (Person)p4.clone(); 29          System.out.println(p4.toString()); 30          System.out.println(p5.toString()); 31          System.out.println(p4 == p5); // is it the same object - should be false 32          System.out.println(p4.equals(p5)); // are they logically equal - should be true 33          System.out.println(p4.hashCode()); 34          System.out.println(p5.hashCode()); // hash codes should be the same 35        }catch(CloneNotSupportedException ignored){ } 36 37         System.out.println(); 38         System.out.println(p1.compareTo(p2)); 39         System.out.println(p1.compareTo(p4)); 40         System.out.println(p4.compareTo(p1)); 41 42      } 43    } // end MainTestApp
image from book

Referring to figure 23-6 — the results of executing the compareTo() method appear at the bottom left of the screen capture. Zero means the objects compared are equal. A negative integer, -1, means the left-hand side object (referenced by p1) is less than the right-hand side object. (The object the left-hand side object is being compared against, which is p4 in this case.) A positive integer, 1, means the left-hand side object is greater than the right-hand side object.

image from book
Figure 23-6: Results of Running Example 23.10

Quick Review

Implement the Comparable interface when a class of objects will be utilized in a collection and will therefore be subject to a natural ordering. It is recommended that the Comparable.compareTo() method perform consistently with the equals() method.




Java For Artists(c) The Art, Philosophy, and Science of Object-Oriented Programming
Java For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504052
EAN: 2147483647
Year: 2007
Pages: 452

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net