// Sorting Comparable and Comparator using Generics
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
// don't need import java.lang.Comparable;

...
/**
 * List of filename/count pairs
 */
static final ArrayList<Pair> listOfPairs = new ArrayList<Pair>();

/**
 * Array of filenam/count pairs
 */
static final Pair[] arrayOfPairs = new Pair[ 40 ];
...

/**
 * test harness
 *
 * @param args not used
 */
public static void main ( String[] args )
   {
   ...

   // note. the compiler will often complain here about problems in the Comparable or Comparator.
   Collections.sort( listOfPairs ); // alphabetically
   ...
   Collections.sort( listOfPairs, new Numerically() );
   ...
   Arrays.sort ( arrayOfpairs ); // alphabetically
   ...
   Arrays.sort ( arrayOfPairs, new Numerically() );

   }

/**
 * Class to represent an Filename/Count pair.
 */
class Pair implements Comparable<Pair>  // <---  note <Pair>
   {
   /**
    * The name of one file to be described.
    */
   String filename;

   /**
    * hit count.
    */
   int count;

   /**
    * Constructor.
    */
   Pair ( String filename, int count )
      {
      this.filename = filename;
      this.count = count;
      }

   /**
    * Compare two Pairs. Callback for natural order sort.
    * effectively returns a-b;
    * @return +1, a>b, 0 a=b, -1 a<b, case-insensitive
    */
   public final int compareTo ( Pair b )   // <--- note Pair, not Object
      {
      // compare filenames.
      return this.filename.compareToIgnoreCase( b.filename );    // <--- note lack of (Pair) cast
      } // end compareTo

   } // end class Pair

//-----------------------------------

class Numerically implements Comparator<Pair>  // <--- note <Pair>
   {
   /**
     * Compare two Pairs. Callback for sort. DESCENDING numerically, ascending by name
     * effectively returns b-a;
     * @return +1, b>a, 0 a=b, -1 b<a, case insenstive
     */
   public final int compare( Pair a, Pair b )  // <--- note Pair not Object
      {
      int diff =  b.count - a.count;  // <--- note lack of Casts
      if ( diff == 0 )
         {
         return a.filename.compareToIgnoreCase( b.filename );
         }
      else
         {
         return diff;
         }
      } // end compare

   } // end class Numerically