1 cananian 1.1.2.1 // MapComparator.java, created Mon Sep 17 17:16:46 2001 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 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.2 import java.util.ArrayList; 7 cananian 1.1.2.2 import java.util.Collections; 8 cananian 1.1.2.2 import java.util.Comparator; 9 cananian 1.3 import java.util.List; 10 cananian 1.1.2.2 import java.util.Map; 11 cananian 1.3 12 cananian 1.3 import net.cscott.jutil.Default; 13 cananian 1.1.2.1 /** 14 cananian 1.1.2.1 * A <code>MapComparator</code> compares two unsorted maps by first 15 cananian 1.1.2.1 * sorting their keys and then comparing them entry-by-entry (treating 16 cananian 1.1.2.1 * the map as a sorted pair list). 17 cananian 1.1.2.1 * 18 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 19 cananian 1.3 * @version $Id: MapComparator.java,v 1.3 2004/02/08 01:56:15 cananian Exp $ 20 cananian 1.1.2.1 */ 21 cananian 1.3 public class MapComparator<K,V> implements Comparator<Map<K,V>> { 22 cananian 1.3 final Comparator<Map.Entry<K,V>> entryComparator; 23 cananian 1.3 final Comparator<List<Map.Entry<K,V>>> listComparator; 24 cananian 1.1.2.1 25 cananian 1.1.2.1 /** Creates a <code>MapComparator</code> which compares 26 cananian 1.1.2.1 * entries in the order defined by the <code>keyComparator</code> 27 cananian 1.1.2.1 * and compares keys (using <code>keyComparator</code>) before values 28 cananian 1.1.2.1 * (using <code>valueComparator</code>). 29 cananian 1.1.2.1 * If <code>keyComparator</code> is <code>null</code>, then all 30 cananian 1.1.2.1 * keys must implement <code>java.lang.Comparable</code>. 31 cananian 1.1.2.1 * If <code>valueComparator</code> is <code>null</code>, then all 32 cananian 1.1.2.1 * values must implement <code>java.lang.Comparable</code>. 33 cananian 1.1.2.1 */ 34 cananian 1.3 public MapComparator(Comparator<? super K> keyComparator, 35 cananian 1.3 Comparator<? super V> valueComparator) { 36 cananian 1.3 if (keyComparator==null) keyComparator = Default.<K>comparator(); 37 cananian 1.3 if (valueComparator==null) valueComparator = Default.<V>comparator(); 38 cananian 1.1.2.1 this.entryComparator = 39 cananian 1.3 new EntryComparator<K,V>(keyComparator, valueComparator); 40 cananian 1.3 this.listComparator = 41 cananian 1.3 new ListComparator<Map.Entry<K,V>>(true, entryComparator); 42 cananian 1.1.2.1 } 43 cananian 1.1.2.1 44 cananian 1.3 public int compare(Map<K,V> m1, Map<K,V> m2) { 45 cananian 1.3 ArrayList<Map.Entry<K,V>> 46 cananian 1.3 al1 = new ArrayList<Map.Entry<K,V>>(m1.entrySet()), 47 cananian 1.3 al2 = new ArrayList<Map.Entry<K,V>>(m2.entrySet()); 48 cananian 1.1.2.1 Collections.sort(al1, entryComparator); 49 cananian 1.1.2.1 Collections.sort(al2, entryComparator); 50 cananian 1.1.2.1 return listComparator.compare(al1, al2); 51 cananian 1.1.2.1 } 52 cananian 1.3 private static class EntryComparator<K,V> 53 cananian 1.3 implements Comparator<Map.Entry<K,V>> { 54 cananian 1.3 final Comparator<? super K> keyComparator; 55 cananian 1.3 final Comparator<? super V> valueComparator; 56 cananian 1.3 EntryComparator(Comparator<? super K> keyComparator, 57 cananian 1.3 Comparator<? super V> valueComparator) { 58 cananian 1.1.2.1 this.keyComparator = keyComparator; 59 cananian 1.1.2.1 this.valueComparator = valueComparator; 60 cananian 1.1.2.1 } 61 cananian 1.3 public int compare(Map.Entry<K,V> me1, Map.Entry<K,V> me2) { 62 cananian 1.1.2.1 int c = keyComparator.compare(me1.getKey(), me2.getKey()); 63 cananian 1.1.2.1 if (c!=0) return c; 64 cananian 1.1.2.1 return valueComparator.compare(me1.getValue(), me2.getValue()); 65 cananian 1.1.2.1 } 66 cananian 1.1.2.1 } 67 cananian 1.2 }