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 }