1 cananian 1.1.2.1 // ListComparator.java, created Wed Feb 24 15:33:11 1999 by cananian
 2 cananian 1.1.2.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1.2.1 package harpoon.Util;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.1 import java.util.Comparator;
 7 cananian 1.1.2.1 import java.util.List;
 8 cananian 1.1.2.1 import java.util.ListIterator;
 9 cananian 1.1.2.1 /**
10 cananian 1.1.2.1  * A <code>ListComparator</code> compares two lists element-by-element.
11 cananian 1.1.2.1  * 
12 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
13 cananian 1.3      * @version $Id: ListComparator.java,v 1.3 2004/02/08 01:56:15 cananian Exp $
14 cananian 1.1.2.1  */
15 cananian 1.3     public class ListComparator<T> implements Comparator<List<T>> {
16 cananian 1.1.2.1     final boolean cmpForwards;
17 cananian 1.3         final Comparator<? super T> elementComparator;
18 cananian 1.1.2.1     
19 cananian 1.1.2.1     /** Creates a <code>ListComparator</code> which compares
20 cananian 1.1.2.1      *  elements first-to-last.  All elements of the list must
21 cananian 1.1.2.1      *  implement <code>java.lang.Comparable</code>. */
22 cananian 1.1.2.1     public ListComparator() {
23 cananian 1.1.2.1         this.cmpForwards = true;
24 cananian 1.1.2.1         this.elementComparator=null;
25 cananian 1.1.2.1     }
26 cananian 1.1.2.1     /** Creates a <code>ListComparator</code>.  If <code>cmpForwards</code>
27 cananian 1.1.2.1      *  is <code>true</code>, compares elements first-to-last, otherwise
28 cananian 1.1.2.1      *  compares them last-to-first.  If <code>elementComparator</code>
29 cananian 1.1.2.1      *  is <code>null</code>, then all elements of the list must
30 cananian 1.1.2.1      *  implement <code>java.lang.Comparable</code> and the
31 cananian 1.1.2.1      *  <code>ListComparator</code> uses their natural ordering.  Otherwise,
32 cananian 1.1.2.1      *  it uses the supplied <code>Comparator</code> to compare elements.
33 cananian 1.1.2.1      */
34 cananian 1.3         public ListComparator(boolean cmpForwards,
35 cananian 1.3                               Comparator<? super T> elementComparator) {
36 cananian 1.1.2.1         this.cmpForwards = cmpForwards;
37 cananian 1.1.2.1         this.elementComparator=elementComparator;
38 cananian 1.1.2.1     }
39 cananian 1.1.2.1 
40 cananian 1.3         public int compare(List<T> l1, List<T> l2) {
41 cananian 1.1.2.1         // throws ClassCastException if objects are not the proper types.
42 cananian 1.3             ListIterator<T> li1 = l1.listIterator(cmpForwards?0:l1.size());
43 cananian 1.3             ListIterator<T> li2 = l2.listIterator(cmpForwards?0:l2.size());
44 cananian 1.1.2.1         if (cmpForwards) {
45 cananian 1.1.2.1             while (li1.hasNext() && li2.hasNext()) {
46 cananian 1.1.2.1                 int cmp = compareElement(li1.next(), li2.next());
47 cananian 1.1.2.1                 if (cmp!=0) return cmp;
48 cananian 1.1.2.1             }
49 cananian 1.1.2.1         } else {
50 cananian 1.1.2.1             while (li1.hasPrevious() && li2.hasPrevious()) {
51 cananian 1.1.2.1                 int cmp = compareElement(li1.previous(), li2.previous());
52 cananian 1.1.2.1                 if (cmp!=0) return cmp;
53 cananian 1.1.2.1             }
54 cananian 1.1.2.1         }
55 cananian 1.1.2.1         // for lists of unequal length, the shorter is the smaller.
56 cananian 1.1.2.1         return l1.size() - l2.size();
57 cananian 1.1.2.1     }
58 cananian 1.3         private int compareElement(T o1, T o2) {
59 cananian 1.1.2.1         if (elementComparator!=null)
60 cananian 1.1.2.1             return elementComparator.compare(o1, o2);
61 cananian 1.1.2.1         else // throws ClassCastException if objects are not comparable.
62 cananian 1.1.2.1             return ((Comparable)o1).compareTo(o2);
63 cananian 1.1.2.1     }
64 cananian 1.2     }