package com.googlecode.totallylazy.comparators; import com.googlecode.totallylazy.functions.Function1; import com.googlecode.totallylazy.functions.Callables; import com.googlecode.totallylazy.Pair; import com.googlecode.totallylazy.Sequence; import com.googlecode.totallylazy.Sequences; import java.util.Comparator; import static com.googlecode.totallylazy.Callers.call; import static com.googlecode.totallylazy.Sequences.sequence; import static com.googlecode.totallylazy.Unchecked.cast; public class Comparators { public static <T, R> Comparator<T> by(final Function1<? super T, ? extends R> callable, final Comparator<? super R> comparator) { return (instance, otherInstance) -> comparator.compare(call(callable, instance), call(callable, otherInstance)); } public static <T, R> Comparator<T> where(final Function1<? super T, ? extends R> callable, final Comparator<? super R> comparator) { return by(callable, comparator); } public static <A, B> Comparator<Pair<A, B>> first(final Comparator<A> comparator) { return by(Callables.<A>first(), comparator); } public static <A, B> Comparator<Pair<A, B>> second(final Comparator<B> comparator) { return by(Callables.<B>second(), comparator); } @SuppressWarnings("unchecked") private static final Comparator<Comparable> ASCENDING = (a, b) -> a.compareTo(b); public static <T extends Comparable<? super T>> Comparator<T> ascending() { return cast(ASCENDING); } public static <T extends Comparable<? super T>> Comparator<T> ascending(Class<T> aClass) { return Comparators.<T>ascending(); } public static <T, R extends Comparable<? super R>> Comparator<T> ascending(final Function1<? super T, ? extends R> callable) { return new AscendingComparator<T, R>(callable); } @SuppressWarnings("unchecked") private static final Comparator<Comparable> DESCENDING = (a, b) -> b.compareTo(a); public static <T extends Comparable<? super T>> Comparator<T> descending() { return cast(DESCENDING); } public static <T extends Comparable<? super T>> Comparator<T> descending(Class<T> aClass) { return Comparators.<T>descending(); } public static <T, R extends Comparable<? super R>> Comparator<T> descending(final Function1<? super T, ? extends R> callable) { return new DescendingComparator<T, R>(callable); } @SafeVarargs public static <T> Comparator<T> comparators(final Comparator<? super T>... comparators) { return comparators(sequence(comparators)); } public static <T> Comparator<T> comparators(final Sequence<Comparator<? super T>> comparators) { return new CompositeComparator<T>(comparators); } public static <T> Comparator<T> comparators(final Comparator<? super T> first) { return comparators(Sequences.<Comparator<? super T>>sequence(first)); } public static <T> Comparator<T> comparators(final Comparator<? super T> first, final Comparator<? super T> second) { return comparators(Sequences.<Comparator<? super T>>sequence(first, second)); } public static <T> Comparator<T> comparators(final Comparator<? super T> first, final Comparator<? super T> second, final Comparator<? super T> third) { return comparators(Sequences.<Comparator<? super T>>sequence(first, second, third)); } public static <T> Comparator<T> comparators(final Comparator<? super T> first, final Comparator<? super T> second, final Comparator<? super T> third, final Comparator<? super T> fourth) { return comparators(Sequences.<Comparator<? super T>>sequence(first, second, third, fourth)); } public static <T> Comparator<T> comparators(final Comparator<? super T> first, final Comparator<? super T> second, final Comparator<? super T> third, final Comparator<? super T> fourth, final Comparator<? super T> fifth) { return comparators(Sequences.<Comparator<? super T>>sequence(first, second, third, fourth, fifth)); } }