001package org.unix4j.util.sort;
002
003import java.util.Arrays;
004import java.util.Comparator;
005import java.util.List;
006
007/**
008 * A comparator based on a list of underlying comparators used in the specified
009 * order. If the first underlying comparator returns a value different from 0
010 * indicating non-equality, the value is returned. If all underlying comparators
011 * return 0, this composite comparator returns 0.
012 */
013public final class CompositeComparator<T> implements Comparator<T> {
014
015        private final List<Comparator<? super T>> comparators;
016
017        /**
018         * Constructs a comparator based on the specified underlying comparators.
019         * 
020         * @param comparators
021         *            the underlying comparators
022         */
023        @SuppressWarnings("unchecked")
024        public CompositeComparator(Comparator<? super T>... comparators) {
025                this(Arrays.asList(comparators));
026        }
027
028        /**
029         * Constructs a comparator based on the specified underlying comparators.
030         * 
031         * @param comparator1
032         *            the first underlying comparators
033         * @param comparator2
034         *            the second underlying comparators
035         */
036        @SuppressWarnings("unchecked")
037        public CompositeComparator(Comparator<? super T> comparator1, Comparator<? super T> comparator2) {
038                this(new Comparator[] { comparator1, comparator2 });
039        }
040
041        /**
042         * Constructs a comparator based on the specified underlying comparators.
043         * 
044         * @param comparator1
045         *            the first underlying comparators
046         * @param comparator2
047         *            the second underlying comparators
048         * @param comparator3
049         *            the third underlying comparators
050         */
051        @SuppressWarnings("unchecked")
052        public CompositeComparator(Comparator<? super T> comparator1, Comparator<? super T> comparator2, Comparator<? super T> comparator3) {
053                this(new Comparator[] { comparator1, comparator2, comparator3 });
054        }
055
056        /**
057         * Constructs a comparator based on the specified underlying comparators.
058         * 
059         * @param comparators
060         *            the underlying comparators
061         */
062        public CompositeComparator(List<Comparator<? super T>> comparators) {
063                this.comparators = comparators;
064        }
065
066        @Override
067        public int compare(T o1, T o2) {
068                for (final Comparator<? super T> comparator : comparators) {
069                        final int cmp = comparator.compare(o1, o2);
070                        if (cmp != 0) {
071                                return cmp;
072                        }
073                }
074                return 0;
075        }
076}