package com.limegroup.gnutella.util; import java.io.Serializable; import java.util.Comparator; /** * Utility class that uses the strategy pattern for <tt>Comparator</tt> * instances. This is possible because all comparators implement the * <tt>Comparator</tt> interface. This allows all classes using these * comparators to use the same instances, reducing object creation. Many of * these comparators are only necessary because the Java 1.1.8 versions of * their classes did not implement the <tt>Comparable</tt> interface. */ public final class Comparators { /** * <tt>Comparator</tt> for comparing two <tt>Integer</tt>s. */ private static final Comparator INT_COMPARATOR = new IntComparator(); /** * <tt>Comparator</tt> for comparing two <tt>Long</tt>s. */ private static final Comparator LONG_COMPARATOR = new LongComparator(); /** * Inverse <tt>Comparator</tt> for comparing two <tt>Long</tt>s. */ private static final Comparator INVERSE_LONG_COMPARATOR = new InverseLongComparator(); /** * <tt>Comparator</tt> for comparing two <tt>String</tt>s. */ private static final Comparator STRING_COMPARATOR = new StringComparator(); /** * <tt>Comparator</tt> for comparing two <tt>File</tt>s. */ private static final Comparator FILE_COMPARATOR = new FileComparator(); /** * <tt>Comparator</tt> for comparing two <tt>String</tt>s regardless of * case. */ private static final Comparator CASE_INSENSITIVE_STRING_COMPARATOR = new CaseInsensitiveStringComparator(); /** * Ensure that this class cannot be constructed. */ private Comparators() {} /** * Instance accessor for the <tt>Comparator</tt> for <tt>Integer</tt>s. * This is necessary because the <tt>Integer</tt> class did not implement * <tt>Comparable</tt> in Java 1.1.8. This is an instance because the * <tt>IntComparator</tt> has no state, allowing a single instance to be * used whenever a <tt>Comparator</tt> is needed for <tt>Integer</tt>s. * * @return the <tt>IntComparator</tt> instance */ public static Comparator integerComparator() { return INT_COMPARATOR; } /** * Instance accessor for the <tt>Comparator</tt> for <tt>Long</tt>s. This * is necessary because the <tt>Long</tt> class did not implement * <tt>Comparable</tt> in Java 1.1.8. This is an instance because the * <tt>LongComparator</tt> has no state, allowing a single instance to be * used whenever a <tt>Comparator</tt> is needed for <tt>Long</tt>s. * * @return the <tt>LongComparator</tt> instance */ public static Comparator longComparator() { return LONG_COMPARATOR; } /** * Instance accessor for the inverse <tt>Comparator</tt> for <tt>Long</tt>s. * This is necessary because the <tt>Long</tt> class did not implement * <tt>Comparable</tt> in Java 1.1.8. This is an instance because the * <tt>LongComparator</tt> has no state, allowing a single instance to be * used whenever a <tt>Comparator</tt> is needed for <tt>Long</tt>s. * * @return the <tt>LongComparator</tt> instance */ public static Comparator inverseLongComparator() { return INVERSE_LONG_COMPARATOR; } /** * Instance accessor for the <tt>Comparator</tt> for <tt>String</tt>s. This * is necessary because the <tt>String</tt> class did not implement * <tt>Comparable</tt> in Java 1.1.8. This is an instance because the * <tt>StringComparator</tt> has no state, allowing a single instance to be * used whenever a <tt>Comparator</tt> is needed for <tt>String</tt>s. * * @return the <tt>StringComparator</tt> instance */ public static Comparator stringComparator() { return STRING_COMPARATOR; } /** * Instance accessor for the <tt>Comparator</tt> for <tt>File</tt>s. This * is necessary because the <tt>File</tt> class did not implement * <tt>Comparable</tt> in Java 1.1.8. This is an instance because the * <tt>FileComparator</tt> has no state, allowing a single instance to be * used whenever a <tt>Comparator</tt> is needed for <tt>File</tt>s. * * @return the <tt>FileComparator</tt> instance */ public static Comparator fileComparator() { return FILE_COMPARATOR; } /** * Instance accessor for the <tt>Comparator</tt> for case insensitive * <tt>String</tt>s. This is an instance because the * <tt>CaseInsensitiveStringComparator</tt> has no state, allowing a single * instance to be used whenever a <tt>Comparator</tt> is needed. * * @return the <tt>CaseInsensitiveStringComparator</tt> instance */ public static Comparator caseInsensitiveStringComparator() { return CASE_INSENSITIVE_STRING_COMPARATOR; } /** * Compares two Integers. */ private static final class IntComparator implements Comparator, Serializable { private static final long serialVersionUID = 830281396810831681L; public int compare(Object o1, Object o2) { return intCompareTo((Integer)o1, (Integer)o2); } } /** * Compares two <tt>Long</tt>s. Useful for storing Java * 1.1.8 <tt>Long</tt>s in Java 1.2+ sorted collections classes. This is * needed because <tt>Long</tt>s in 1.1.8 do not implement the * <tt>Comparable</tt> interface, unlike <tt>Long</tt>s in 1.2+. */ private static final class LongComparator implements Comparator, Serializable { private static final long serialVersionUID = 226428887996180051L; public int compare(Object o1, Object o2) { return longCompareTo((Long)o1, (Long)o2); } } /** * Inverse comparison for two <tt>Long</tt>s. Useful for storing Java * 1.1.8 <tt>Long</tt>s in Java 1.2+ sorted collections classes. This is * needed because <tt>Long</tt>s in 1.1.8 do not implement the * <tt>Comparable</tt> interface, unlike <tt>Long</tt>s in 1.2+. */ private static final class InverseLongComparator implements Comparator, Serializable { private static final long serialVersionUID = 316426787496198051L; public int compare(Object o1, Object o2) { return -longCompareTo((Long)o1, (Long)o2); } } /** * Compares to <tt>String</tt> objects. The comparison is done * without regard to case. */ public static final class CaseInsensitiveStringComparator implements Comparator, Serializable { private static final long serialVersionUID = 263123571237995212L; public int compare(Object o1, Object o2) { return StringUtils.compareIgnoreCase((String)o1, (String)o2); } } /** * Compares two Integer objects numerically. This function is identical * to the Integer compareTo method. The Integer compareTo method * was added in Java 1.2, however, so any app that is 1.1.8 compatible * must use this method. */ public static int intCompareTo(Integer thisInt, Integer anotherInt) { int thisVal = thisInt.intValue(); int anotherVal = anotherInt.intValue(); return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1)); } /** * Compares two <code>Long</code> objects numerically. This function is * identical to the Long compareTo method. The Long compareTo method was * added in Java 1.2, however, so any app that is 1.1.8 compatible must use * this method. * * @param firstLong the first <code>Long</code> to be compared. * @param secondLong the second <code>Long</code> to be compared. * @return the value <code>0</code> if the first <code>Long</code> * argument is equal to the second <code>Long</code> argument; a value * less than <code>0</code> if the first <code>Long</code> argument is * numerically less than the second <code>Long</code>; and a * value greater than <code>0</code> if the first <code>Long</code> * argument is numerically greater than the second <code>Long</code> * argument (signed comparison). */ public static int longCompareTo(Long firstLong, Long secondLong) { long firstVal = firstLong.longValue(); long secondVal = secondLong.longValue(); return (firstVal<secondVal ? -1 : (firstVal==secondVal ? 0 : 1)); } }