001 package edu.nrao.sss.sort; 002 003 import java.util.Comparator; 004 005 /** 006 * A {@link SortKey sort key} and {@link Comparator comparator} that works with 007 * the {@code Double}s returned by a method that is found reflectively. 008 * <p> 009 * Clients of this class must provide the name of a public, no argument, method 010 * that returns a {@code Double} and that is present in classes of the 011 * parameterized type {@code T}. The method created from that name is called 012 * on the objects to be compared, and the doubles returned from those methods 013 * are what is actually compared.</p> 014 * <p> 015 * Because this class is a {@link SortKey}, you may configure its instances with 016 * a particular {@code SortOrder}. You may place instances of this 017 * class in a {@link CompoundComparator}.</p> 018 * <p> 019 * <b><u>Example</u></b><br/> 020 * Let there be a class, <tt>Pants</tt>, that has the following 021 * attributes, each of which is a <tt>double</tt>: 022 * <tt>waist, inseam, price</tt>, and a <tt>String</tt> attribute: 023 * <tt>style</tt>. Furthermore, assume the normal convention 024 * for the getters (e.g., <tt>getPrice()</tt>). You could sort a collection of 025 * pants by waist, then price, then style, then inseam, without writing any new 026 * classes by doing this:</p> 027 * <pre> 028 * ReflectiveDoubleSortKey<Pants> waistKey = 029 * new ReflectiveDoubleSortKey<Pants>("getWaist"); 030 * 031 * ReflectiveDoubleSortKey<Pants> lengthKey = 032 * new ReflectiveDoubleSortKey<Pants>("getInseam"); 033 * 034 * ReflectiveDoubleSortKey<Pants> costKey = 035 * new ReflectiveDoubleSortKey<Pants>("getPrice"); 036 * 037 * ReflectiveStringSortKey<Pants> styleKey = 038 * new ReflectiveStringSortKey<Pants>("getStyle"); 039 * 040 * CompoundComparator<Pants> comparator = 041 * new CompoundComparator<Pants>(waistKey, priceKey, styleKey, lengthKey); 042 * 043 * Collections.sort(pantsCatalog, comparator); 044 * </pre> 045 * <p> 046 * <b>Version Info:</b> 047 * <table style="margin-left:2em"> 048 * <tr><td>$Revision: 593 $</td></tr> 049 * <tr><td>$Date: 2007-05-07 15:54:14 -0600 (Mon, 07 May 2007) $</td></tr> 050 * <tr><td>$Author: dharland $</td></tr> 051 * </table></p> 052 * 053 * @author David M. Harland 054 * @since 2007-05-04 055 */ 056 public final class ReflectiveDoubleSortKey<T> 057 extends DoubleSortKey 058 implements Comparator<T> 059 { 060 private ReflectiveSortHelper<Double, T> helper; 061 062 /** 063 * Creates a new instance that will base its comparison on the {@code Double} 064 * returned by the method with the given name. 065 * 066 * @param methodName the name of a public, no argument, method that belongs 067 * to objects of type {@code T} and that returns a 068 * {@code Double} (or {@code double}). If there is any 069 * trouble creating or calling the method with this name, 070 * it will be treated as if it returns a {@code Double} 071 * of {@link Double#NaN}. 072 */ 073 public ReflectiveDoubleSortKey(String methodName) 074 { 075 helper = new ReflectiveSortHelper<Double, T>(methodName, Double.NaN); 076 } 077 078 /** 079 * Sets the name of the method used for making comparisons. 080 * 081 * @param newMethodName the name of a public, no argument, method that belongs 082 * to objects of type {@code T} and that returns a 083 * {@code Double} (or {@code double}). If there is any 084 * trouble creating or calling the method with this name, 085 * it will be treated as if it returns a {@code Double} 086 * of {@link Double#NaN}. 087 */ 088 public void setMethodName(String newMethodName) 089 { 090 helper.setMethodName(newMethodName); 091 } 092 093 /* (non-Javadoc) 094 * @see Comparator#compare(Object, Object) 095 */ 096 public int compare(T o1, T o2) 097 { 098 return compareObjects(helper.getValue(o1), helper.getValue(o2)); 099 } 100 }