SDSU CS 535: Object-Oriented Programming & Design
Fall Semester, 1997
Doc 13, Sorting - An Example

To Lecture Notes Index
San Diego State University -- This page last updated 05-Oct-97

Contents of Doc 13, Sorting - An Example

  1. References
  2. Sorting - An Example
    1. Solution 1
    2. Sort Solution 2
      1. Inheritance verses Object Composition
      2. A Better SortedList - Override Compare Method
      3. Problems with BetterSortedList
    3. Solution 3 - Create Comparer Class
      1. Sorting in Other Languages
      2. Languages and Countries Available

References


Design Patterns: Elements of Resuable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, Addision-Wesley, 1995

On-line Java 1.1.3 API Documentation

Doc 13, Sorting - An Example Slide # 1

Sorting - An Example


Vague Goal - Produce a general purpose sorter

Solution 1


Use interface Comparable and Sort class
/**
  * Comparable interface contains the methods that
  * a class must implement if you want the sort method to
  * sort objects of that class
  */

interface Comparable
   {
   /**
    * Returns true if current object is less than otherObject
    */
   public boolean lessThan( Comparable otherObject );

   public boolean greaterThan( Comparable otherObject );

   public boolean equal( Comparable otherObject );
   }


Doc 13, Sorting - An Example Slide # 2
Example use of Comparable - StudentRecord
class StudentRecord implements Comparable
   {
   private final int ID;
   private String name;
   private float GradePointAverage;
   
   public StudentRecord( int uniqueID, String studentName)
      {
      name = studentName;
      ID = uniqueID;
      }

   public String toString() {  return name;   }

   public boolean lessThan( Comparable aStudent )
      {
      StudentRecord otherStudent = 
                              (StudentRecord) aStudent;
      return ID < otherStudent.ID;
      }
      
   public boolean greaterThan( Comparable aStudent )
      {
      StudentRecord otherStudent = (StudentRecord) aStudent;
      return ID > otherStudent.ID;
      }

   public boolean equal( Comparable aStudent )
      {
      StudentRecord otherStudent =  (StudentRecord) aStudent;
      return ID == otherStudent.ID;
      }
   }

Doc 13, Sorting - An Example Slide # 3
Using StudentRecord
class Test
   {
   public  static  void  main( String  args[] ) 
   {
      StudentRecord goodStudent = 
                     new StudentRecord( 1, "Roger");

      StudentRecord bestStudent = 
                     new StudentRecord( 2, "Sam");
   
      if ( goodStudent.greaterThan( bestStudent ) )
         System.out.println(  "good is greater" );
      else
         System.out.println(  "good is less" );
      }
   }
Output
good is less

Doc 13, Sorting - An Example Slide # 4
Sorter

class Sorter
   {
   public static final void sort( Comparable[] list )
      {
      for ( int unsortedElementIndex = 1; 
            unsortedElementIndex < list.length; 
            unsortedElementIndex++ 
           )
         {
         Comparable insertMe;
         insertMe = list[ unsortedElementIndex ];

         int insertIndex = unsortedElementIndex;
         
         while ( (insertIndex > 0) &&
                   list[ insertIndex - 1 ].greaterThan( insertMe )
                  )
            {
            list[insertIndex] = list[insertIndex-1];
            insertIndex--;
            }

         list[insertIndex] = insertMe;
         }
      } // end sort

   } // end class

Doc 13, Sorting - An Example Slide # 5
Using Sorter
class Test
   {
   public  static  void  main( String  args[] ) 
      {

      StudentRecord[] classList = new StudentRecord[ 4];

      classList[0] = new StudentRecord( 5, "Roger");
      classList[1] = new StudentRecord( 2, "Roberto");
      classList[2] = new StudentRecord( 8, "Victor");
      classList[3] = new StudentRecord( 3, "Sergio");
      
      Sorter.sort( classList );

      for ( int studentIndex = 0;
            studentIndex < classList.length; 
            studentIndex++ 
            )
         System.out.println( classList[studentIndex]);
            
      }
   }
Output
Roberto
Sergio
Roger
Victor

Doc 13, Sorting - An Example Slide # 6
What is Wrong with Sorter?
Doc 13, Sorting - An Example Slide # 7
What Operations would you want on a SortedList?


Doc 13, Sorting - An Example Slide # 8
The Plot Thickens

There are times when you want to sort a list of StudentRecords by:
Id
Name
Grade

Sort Solution 2




SortedList Class - contains all the great methods listed on previous slide

SortByName - contains one method which sorts by name

SortByID - contains one method which sorts by ID

SortByGrade - contains one method which sorts by Grade

Doc 13, Sorting - An Example Slide # 9
SortedList
abstract class SortedList
   {
   private Vector list;
   
   public SortedList( int size )
      {
      list = new Vector( size);
      }
      
   public Enumeration elements()
      {
      return list.elements();
      }
   
   public String toString()
      {
      return list.toString();
      }
   
   public Object elementAt( int index)
      {
      return list.elementAt( index);
      }
      
   public void addElement( Object addMe )
      {
      list.addElement( addMe);
      sort( list);
      }
   
   abstract protected void sort( Vector unsorted);
   }

Some useful methods not included to save space

Doc 13, Sorting - An Example Slide # 10
SortedList Subclasses
class SortByID extends SortedList
   {
   public SortByID( int size)
      {
      super(size);
      }
   protected void sort( Vector list)
      {
      for    ( int newItemIndex = 1; 
               newItemIndex < list.size(); 
               newItemIndex++ 
            )
         {
         StudentRecord insertItem = (StudentRecord) 
                              list.elementAt( newItemIndex );
         int insertIndex = newItemIndex;
         
         while (insertIndex > 0)
            {
            StudentRecord nextItem = (StudentRecord) 
                              list.elementAt(insertIndex - 1 );

            if ( nextItem.getID() > insertItem.getID() )
               {
               list.setElementAt( 
                     list.elementAt( insertIndex -1), 
                     insertIndex);
               insertIndex--;
               }
            else
               break;
            }
         list.setElementAt( insertItem, insertIndex) ;
         }
      }
   }

Doc 13, Sorting - An Example Slide # 11
SortedList Subclasses
class SortByName extends SortedList
   {
   public SortByName( int size)
      {
      super(size);
      }
   protected void sort( Vector list)
      {
      for ( int newItemIndex = 1; 
               newItemIndex < list.size(); 
               newItemIndex++ )
         {
         StudentRecord insertItem = (StudentRecord) 
                              list.elementAt( newItemIndex );
         int insertIndex = newItemIndex;

         while (insertIndex > 0)
            {
            StudentRecord nextItem = (StudentRecord) 
                              list.elementAt(insertIndex - 1 );
            if ( nextItem.getName().compareTo(
                        insertItem.getName())  > 0 )
               {
               list.setElementAt(    
                     list.elementAt( insertIndex -1), 
                     insertIndex);
               insertIndex--;
               }
            else
               break;
            }
         list.setElementAt( insertItem, insertIndex) ;
         }
      }
   }

Doc 13, Sorting - An Example Slide # 12
Sample use of SortedList
class Test
   {
   public  static  void  main( String  args[] ) 
      {
      SortedList list = new SortByName( 4);
      list.addElement( new StudentRecord( 5, "Roger") );
      list.addElement( new StudentRecord( 2, "Roberto"));
      list.addElement( new StudentRecord( 8, "Victor"));
      list.addElement(  new StudentRecord( 3, "Sergio"));
      System.out.println( list);

      Enumeration students = list.elements();
      SortedList id = new SortByID( 4 );
      
      while (students.hasMoreElements() )
         id.addElement( students.nextElement() );
      System.out.println( id);
      }
   }

Output
[Roberto, Roger, Sergio, Victor]
[Roberto, Sergio, Roger, Victor]

Doc 13, Sorting - An Example Slide # 13
Why not Subclass Vector?
abstract class SortedList extends Vector
   {
   
   public SortedList( int size )
      {
      super( size);
      }
      
   public void addElement( Object addMe )
      {
      list.addElement( addMe);
      sort( list);
      }
   
   abstract protected void sort( Vector unsorted);
   }


Doc 13, Sorting - An Example Slide # 14

Inheritance verses Object Composition


Object Composition
Class B has a field of type class A
Class A is a black box to class B
More flexible than inheritance

Inheritance
Class B is a subclass of A
Simpler to use
Class B can get involved with inner workings of A


Doc 13, Sorting - An Example Slide # 15

A Better SortedList - Override Compare Method


abstract class BetterSortedList
   {
   private Vector list;
   
   public SortedList( int size )
      {
      list = new Vector( size);
      }
      
   public Enumeration elements()
      {
      return list.elements();
      }
   
   public String toString()
      {
      return list.toString();
      }
   
   public Object elementAt( int index)
      {
      return list.elementAt( index);
      }
      
   public void addElement( Object addMe )
      {
      list.addElement( addMe);
      sort( list);
      }
   

Doc 13, Sorting - An Example Slide # 16
//BetterSortedList Continued

   protected void sort( Vector list)
      {
      for ( int newItemIndex = 1; 
            newItemIndex < list.size(); 
            newItemIndex++ 
          )
         {
         StudentRecord insertItem = 
               (StudentRecord) list.elementAt( newItemIndex );

         int insertIndex = newItemIndex;

         while ( (insertIndex > 0) && 
                 isGreaterThan( list.elementAt( insertIndex - 1), 
                                insertItem 
                              )
               )
            {
            list.setElementAt(   list.elementAt( insertIndex -1), 
                                insertIndex
                              );
            insertIndex--;
            }            
         list.setElementAt( insertItem, insertIndex) ;
         }
      }

   abstract protected boolean 
   isGreaterThan( Object a, Object b);
   }


Doc 13, Sorting - An Example Slide # 17
BetterSortedList Subclasses

class SortByID extends BetterSortedList
   {
   public SortByID( int size)
      {
      super(size);
      }
      
   protected boolean isGreaterThan( Object a, Object b)
      {
      int leftOperand = ((StudentRecord) a).getID();
      int rightOperand = ((StudentRecord) b).getID();
      return leftOperand >  rightOperand;
      }
   }

class SortByName extends SortedList
   {
   public SortByName( int size)
      {
      super(size);
      }

   protected boolean isGreaterThan( Object a, Object b)
      {
      String leftOperand = ((StudentRecord) a).getName();
      String rightOperand = ((StudentRecord) b).getName();
      
      if ( leftOperand.compareTo( rightOperand) > 0 )
         return true;
      else
         return false;
      }
   }

Doc 13, Sorting - An Example Slide # 18
Sample use of BetterSortedList
class Test
   {
   public  static  void  main( String  args[] ) 
      {
      BetterSortedList list = new SortByName( 4);
      list.addElement( new StudentRecord( 5, "Roger") );
      list.addElement( new StudentRecord( 2, "Roberto"));
      list.addElement( new StudentRecord( 8, "Victor"));
      list.addElement(  new StudentRecord( 3, "Sergio"));
      System.out.println( list);

      Enumeration students = list.elements();
      SortedList id = new SortByID( 4 );
      
      while (students.hasMoreElements() )
         id.addElement( students.nextElement() );
      System.out.println( id);
      }
   }

Doc 13, Sorting - An Example Slide # 19

Problems with BetterSortedList


How does one sort a list of students by name and ID in the same program?

Since isGreaterThan is not part of student, but a sort class, can't use it in other comparisons of student record

Doc 13, Sorting - An Example Slide # 20

Solution 3 - Create Comparer Class

public abstract class Comparer
   {
   
   public abstract boolean lessThan( Object leftOperand, 
                                 Object rightOperand ); 
      
   public abstract  boolean greaterThan( Object leftOperand, 
                                 Object rightOperand ); 

   public abstract boolean equals( Object leftOperand, 
                                 Object rightOperand ); 

   public boolean lessThanOrEqual( Object leftOperand, 
                                 Object rightOperand ) 
      {      
      if ( lessThan( leftOperand, rightOperand) || 
           equals( leftOperand, rightOperand) 
         )
         return true;
      else
         return false;
      }

   public boolean greaterThanOrEqual( Object leftOperand, 
                                    Object rightOperand ) 
      {            
      if ( greaterThan( leftOperand, rightOperand) || 
           equals( leftOperand, rightOperand) 
         )
         return true;
      else
         return false;
      }
   }

Doc 13, Sorting - An Example Slide # 21
StudentRecord Comparers

class StudentIDComparer extends Comparer
   {
   private int getID( Object student )
      {
      return ((StudentRecord) student ).getID();
      }
      
   public boolean lessThan( Object leftOperand, 
                                 Object rightOperand )
      {
      int leftID = getID( leftOperand);
      int rightID = getID( rightOperand);
      return leftID <  rightID;      
      } 
      
   public boolean greaterThan( Object leftOperand, 
                                 Object rightOperand ) 
      {
      int leftID =  getID( leftOperand);
      int rightID = getID( rightOperand);
      return leftID >  rightID;
      }
      
   public boolean equals( Object leftOperand, 
                                 Object rightOperand ) 
      {
      int leftID =  getID( leftOperand);
      int rightID = getID( rightOperand);
      return leftID ==  rightID;
      }
   }

Doc 13, Sorting - An Example Slide # 22
StudentRecord Comparers - Continued


class StudentNameComparer extends Comparer
   {
   private String getName( Object student )
      {
      return ((StudentRecord) student ).getName();
      }

   public boolean lessThan( Object leftOperand, 
                                 Object rightOperand )
      {
      String leftName = getName( leftOperand);
      String rightName = getName( rightOperand);
      
      if ( leftName.compareTo( rightName) < 0 )
         return true;
      else
         return false;
      } 
      
   public boolean greaterThan( Object leftOperand, 
                                 Object rightOperand ) 
      {
      String leftName =  getName( leftOperand);
      String rightName = getName( rightOperand);
      
      if ( leftName.compareTo( rightName) > 0 )
         return true;
      else
         return false;
      }
      

Doc 13, Sorting - An Example Slide # 23
//StudentRecord Comparers - Continued

   public boolean equals( Object leftOperand, 
                                 Object rightOperand ) 
      {
      String leftName =  getName( leftOperand);
      String rightName = getName( rightOperand);
      
      if ( leftName.compareTo( rightName) == 0 )
         return true;
      else
         return false;
      }
   }

Doc 13, Sorting - An Example Slide # 24
The SortedList using Comparers

class SortedList
   {
   private Vector list;
   private Comparer listOrder;
   
   public SortedList( int size, Comparer initialListOrder )
      {
      listOrder = initialListOrder;
      list = new Vector( size);
      }
   
   public void setListOrder( Comparer newListOrder )
      {
      listOrder = newListOrder;
      sort();
      }
      
   public Enumeration elements()
      {
      return list.elements();
      }
   
   public String toString()
      {
      return list.toString();
      }
   
   public Object elementAt( int index)
      {
      return list.elementAt( index);
      }
      
   public void addElement( Object addMe )
      {
      list.addElement( addMe);
      sort();
      }

Doc 13, Sorting - An Example Slide # 25
//The SortedList using Comparers - Continued


   protected void sort( )
      {
      for ( int newItemIndex = 1; 
            newItemIndex < list.size(); 
            newItemIndex++ 
           )
         {
         Object  insertItem =  list.elementAt( newItemIndex );
         int insertIndex = newItemIndex;

         while ( (insertIndex > 0) && 
                  listOrder.greaterThan( 
                                 list.elementAt( insertIndex - 1), 
                                 insertItem )
               )
            {
            list.setElementAt( list.elementAt( insertIndex -1), 
                                          insertIndex);
            insertIndex--;
            }

         list.setElementAt( insertItem, insertIndex) ;
         }
      }
   }

Doc 13, Sorting - An Example Slide # 26
The StudentRecord for use with Comparers

class StudentRecord
   {
   private final int ID;
   private String name;
   private float GradePointAverage;
   
   public StudentRecord( int uniqueID, String studentName)
      {
      name = studentName;
      ID = uniqueID;
      }
   
   public int getID()
      {
      return ID;
      }   

   public String getName()
      {
      return name;
      }
      
   public String toString()
      {
      return name;
      }
   }

Doc 13, Sorting - An Example Slide # 27
Sorting With Comparers

class Test
   {
   public  static  void  main( String  args[] ) 
      {
      SortedList list;

      list = new SortedList( 4, new StudentNameComparer() );

      list.addElement( new StudentRecord( 5, "Roger") );
      list.addElement( new StudentRecord( 2, "Roberto"));
      list.addElement( new StudentRecord( 8, "Victor"));
      list.addElement(  new StudentRecord( 3, "Sergio"));
      System.out.println( list);

      list.setListOrder( new StudentIDComparer() );
      System.out.println( list);
      }
   }

Output
[Roberto, Roger, Sergio, Victor]
[Roberto, Sergio, Roger, Victor]

Doc 13, Sorting - An Example Slide # 28

Sorting in Other Languages

import java.text.Collator;
import java.util.Locale;

class TextComparer extends Comparer
   {
   private Collator textOrder;

   public TextComparer()
      {
      textOrder = Collator.getInstance(); 
      }
      
   public TextComparer( Locale foreignLocation )
      {
      textOrder = Collator.getInstance( foreignLocation ); 
      }
   
   public static TextComparer spanish()
      {
      Locale spanish = new Locale( "es", "ES" );
      return new TextComparer( spanish );
      }
      
   public boolean lessThan( Object leftOperand, 
                                 Object rightOperand )
      {
      String left = (String) leftOperand;
      String right = (String) rightOperand;
      
      if ( textOrder.compare( left, right) < 0 )
         return true;
      else
         return false;
      } 

Doc 13, Sorting - An Example Slide # 29
//TextComparer - Continued
   public boolean greaterThan( Object leftOperand, 
                                 Object rightOperand ) 
      {
      String left =  (String) leftOperand;
      String right = (String) rightOperand;
      
      if ( textOrder.compare( left, right) > 0 )
         return true;
      else
         return false;
      }
      
   public boolean equals( Object leftOperand, 
                                 Object rightOperand ) 
      {
      String left =  (String) leftOperand;
      String right = (String) rightOperand;
      
      if ( textOrder.compare( left, right) == 0 )
         return true;
      else
         return false;
      }
   }


Doc 13, Sorting - An Example Slide # 30
Using the SortedList

class Test
   {
   public  static  void  main( String  args[] ) 
      {
      SortedList list;

      list = new SortedList( 4, TextComparer.spanish() );

      list.addElement( "ch" );
      list.addElement( "ca");
      list.addElement( "cz");
      list.addElement(  "at" );

      System.out.println( list);
      
      }
   }

Output
[at, ca, cz, ch]

Doc 13, Sorting - An Example Slide # 31

Languages and Countries Available

LanguageCountry
ArabicEgypt
BelorussianBelarus
BulgarianBulgaria
CatalanSpain
CzechCzech Republic
DanishDenmark
GermanGermany
GermanAustria
GermanSwitzerland
GreekGreece
EnglishCanada
EnglishUnited Kingdom
EnglishIreland
EnglishUnited States
Spanish - Modern SortSpain
EstonianEstonia
FinnishFinland
FrenchFrance
FrenchBelgium
FrenchCanada
FrenchSwitzerland
CroatianCroatia
HungarianHungary
IcelandicIceland
ItalianItaly
ItalianSwitzerland
HebrewIsrael
JapaneseJapan
KoreanKorea
LithuanianLituania
LatvianLatvia
MacedonianMacedonia
DutchNetherlands
DutchBelgium
Norwegian (BokmÂl)Norway
Norwegian (Nynorsk)Norway
PolishPoland
PortuguesePortugal
RomanianRomania
RussianRussia
Serbian (Latin)Serbia
SlovakSlovakia
SloveneSlovenia
AlbanianAlbania
Serbian (Cyrillic)Serbia
SwedishSweden
TurkishTurkey
UkrainianUkraine
ChineseChina
ChineseROC


Doc 13, Sorting - An Example Slide # 32
From the java.util.Locale API documentation:

You create a Locale object using one of the two constructors in this class:
Locale(String language, String country)
Locale(String language, String country, String variant)

The first argument to both constructors is a valid ISO Language Code. These codes are the lower-case two-letter codes as defined by ISO-639. You can find a full list of these codes at a number of sites, such as:

http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt

The second argument to both constructors is a valid ISO Country Code. These codes are the upper-case two-letter codes as defined by ISO-3166. You can find a full list of these codes at a number of sites, such as:

http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

visitors since 05-Oct-97