package de.skuzzle.polly.tools; import java.util.Arrays; import java.util.Comparator; import java.util.List; /** * This class provides static utilities for working with the {@link Comparator} and * {@link Comparable} interfaces. * * @author Simon Taddiken */ public final class CompareUtils { /** * Comparator implementation that uses several internal comparators which are * executed as long as the next comparator returns 0. * If all comparators return 0, 0 will be returned. Otherwise, the first result != 0 * will be returned. * * @author Simon Taddiken * @param <T> Type to compare. */ private final static class MultiComparator<T> implements Comparator<T> { private final List<Comparator<T>> comps; /** * Creates a new MultiComparator which uses the given list of comparators. * * @param comps The comparators to execute in the order they occur in the list. */ public MultiComparator(List<Comparator<T>> comps) { this.comps = comps; } @Override public int compare(T o1, T o2) { for (final Comparator<T> c : this.comps) { int r = c.compare(o1, o2); if (r != 0) { return r; } } return 0; } } /** * Creates a comparator that internally uses the list of given comparators to * compare to objects. The returned comparator will return 0 if, and only if all * comparators in the given list return 0. Otherwise, it will return the first * result other than zero that any of the comparators in the list returned. * Comparators are called in order they occur in the list. * * @param comps The list of comparators to use. * @return A comparator instance. */ public final static <T> Comparator<T> multiComparator(List<Comparator<T>> comps) { return new MultiComparator<T>(comps); } /** * Creates a comparator that internally uses the array of given comparators to * compare to objects. The returned comparator will return 0 if, and only if all * comparators in the given array return 0. Otherwise, it will return the first * result other than zero that any of the comparators in the array returned. * Comparators are called in order they occur in the array. * * @param comps The list of comparators to use. * @return A comparator instance. */ @SafeVarargs public final static <T> Comparator<T> multiComparator(Comparator<T>... comps) { return new MultiComparator<T>(Arrays.asList(comps)); } /** * Creates a reversed comparator to the given one. That means the resulting * comparator sorts elements in the opposite direction. * * @param c The source comparator. * @return A new comparator with reversed compare direction. */ public final static <T extends Comparator<T>> Comparator<T> reverse(final T c) { return new Comparator<T>() { @Override public int compare(T o1, T o2) { return c.compare(o2, o1); } }; } /** * Creates a {@link Comparator} from a {@link Comparable} object. * * @param type The comparable type of the elements to compare. * @return A new comparator that uses the {@link Comparable#compareTo(Object)} method * to compare two elements. */ public final static <T extends Comparable<T>> Comparator<T> fromComparable( final Class<T> type) { return new Comparator<T>() { @Override public int compare(T o1, T o2) { return o1.compareTo(o2); } }; } /** * Compares any object by the result of their toString methods. */ public final static Comparator<Object> TO_STRING_COMPARATOR = new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } }; private CompareUtils() {} }