001 package edu.nrao.sss.sort; 002 003 import java.util.ArrayList; 004 import java.util.Collection; 005 import java.util.Comparator; 006 import java.util.List; 007 008 /** 009 * A {@link Comparator comparator} that is a chain of other comparators. 010 * <p> 011 * The first comparator in this one's list functions as the primary key, 012 * the next as a secondary key (in case of a tie in primary keys), 013 * and so on.</p> 014 * <p> 015 * Rather than wrapping its internal list, this comparator provides 016 * its list of components for its clients to access directly.</p> 017 * <p> 018 * <b>Version Info:</b> 019 * <table style="margin-left:2em"> 020 * <tr><td>$Revision: 593 $</td></tr> 021 * <tr><td>$Date: 2007-05-07 15:54:14 -0600 (Mon, 07 May 2007) $</td></tr> 022 * <tr><td>$Author: dharland $</td></tr> 023 * </table></p> 024 * 025 * @author David M. Harland 026 * @since 2007-05-03 027 */ 028 public class CompoundComparator<T> 029 implements Comparator<T> 030 { 031 private List<Comparator<T>> comparators; 032 033 /** Creates a new instance with no contained comparators. */ 034 public CompoundComparator() 035 { 036 this((Comparator<T>[])null); 037 } 038 039 /** 040 * Creates a new compound comparator with the given elements. 041 * The constituent comparators are placed onto this one in the 042 * same order they are given to this constructor. 043 * 044 * @param newComparators the comparators held by this one. 045 */ 046 public CompoundComparator(Comparator<T>... newComparators) 047 { 048 comparators = new ArrayList<Comparator<T>>(); 049 050 if (newComparators != null) 051 { 052 for (Comparator<T> c : newComparators) 053 if (c != null) 054 comparators.add(c); 055 } 056 } 057 058 /** 059 * Creates a new compound comparator with the given elements. 060 * The constituent comparators are placed onto this one in the 061 * same order they inhabit in the given collection. 062 * 063 * @param newComparators the comparators held by this one. 064 */ 065 public CompoundComparator(Collection<? extends Comparator<T>> newComparators) 066 { 067 comparators = new ArrayList<Comparator<T>>(); 068 069 if (newComparators != null) 070 { 071 for (Comparator<T> c : newComparators) 072 if (c != null) 073 comparators.add(c); 074 } 075 } 076 077 /** 078 * Returns the list of component comparators held by this one. 079 * <p> 080 * The returned list is the one actually held by this comparator. 081 * Clients who wish to add, remove, or otherwise manipulate the components, 082 * or their status in the list, should work directly with this list.</p> 083 * 084 * @return the list of component comparators held by this one. 085 */ 086 public List<Comparator<T>> getComponents() 087 { 088 return comparators; 089 } 090 091 /* (non-Javadoc) 092 * @see Comparator#compare(Object, Object) 093 */ 094 public int compare(T o1, T o2) 095 { 096 int result = 0; 097 098 for (Comparator<T> c : comparators) 099 { 100 if (c == null || c == this) 101 continue; 102 103 result = c.compare(o1, o2); 104 105 //Stop comparing the first time a comparator detects a difference 106 if (result != 0) 107 break; 108 } 109 110 return result; 111 } 112 }