001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.commons.collections.comparators;
018    
019    import java.io.Serializable;
020    import java.util.Comparator;
021    
022    /**
023     * Reverses the order of another comparator by reversing the arguments
024     * to its {@link #compare(Object, Object) compare} method.
025     * 
026     * @since Commons Collections 2.0
027     * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
028     *
029     * @author Henri Yandell
030     * @author Michael A. Smith
031     * 
032     * @see java.util.Collections#reverseOrder()
033     */
034    public class ReverseComparator implements Comparator, Serializable {
035    
036        /** Serialization version from Collections 2.0. */
037        private static final long serialVersionUID = 2858887242028539265L;
038    
039        /** The comparator being decorated. */
040        private Comparator comparator;
041    
042        //-----------------------------------------------------------------------
043        /**
044         * Creates a comparator that compares objects based on the inverse of their
045         * natural ordering.  Using this Constructor will create a ReverseComparator
046         * that is functionally identical to the Comparator returned by
047         * java.util.Collections.<b>reverseOrder()</b>.
048         * 
049         * @see java.util.Collections#reverseOrder()
050         */
051        public ReverseComparator() {
052            this(null);
053        }
054    
055        /**
056         * Creates a comparator that inverts the comparison
057         * of the given comparator.  If you pass in <code>null</code>,
058         * the ReverseComparator defaults to reversing the
059         * natural order, as per 
060         * {@link java.util.Collections#reverseOrder()}</b>.
061         * 
062         * @param comparator Comparator to reverse
063         */
064        public ReverseComparator(Comparator comparator) {
065            if(comparator != null) {
066                this.comparator = comparator;
067            } else {
068                this.comparator = ComparableComparator.getInstance();
069            }
070        }
071    
072        //-----------------------------------------------------------------------
073        /**
074         * Compares two objects in reverse order.
075         * 
076         * @param obj1  the first object to compare
077         * @param obj2  the second object to compare
078         * @return negative if obj1 is less, positive if greater, zero if equal
079         */
080        public int compare(Object obj1, Object obj2) {
081            return comparator.compare(obj2, obj1);
082        }
083    
084        //-----------------------------------------------------------------------
085        /**
086         * Implement a hash code for this comparator that is consistent with
087         * {@link #equals(Object) equals}.
088         * 
089         * @return a suitable hash code
090         * @since Commons Collections 3.0
091         */
092        public int hashCode() {
093            return "ReverseComparator".hashCode() ^ comparator.hashCode();
094        }
095    
096        /**
097         * Returns <code>true</code> iff <i>that</i> Object is 
098         * is a {@link Comparator} whose ordering is known to be 
099         * equivalent to mine.
100         * <p>
101         * This implementation returns <code>true</code>
102         * iff <code><i>object</i>.{@link Object#getClass() getClass()}</code>
103         * equals <code>this.getClass()</code>, and the underlying 
104         * comparators are equal.
105         * Subclasses may want to override this behavior to remain consistent
106         * with the {@link Comparator#equals(Object) equals} contract.
107         * 
108         * @param object  the object to compare to
109         * @return true if equal
110         * @since Commons Collections 3.0
111         */
112        public boolean equals(Object object) {
113            if(this == object) {
114                return true;
115            } else if(null == object) {
116                return false;
117            } else if(object.getClass().equals(this.getClass())) {
118                ReverseComparator thatrc = (ReverseComparator)object;
119                return comparator.equals(thatrc.comparator);
120            } else {
121                return false;
122            }
123        }
124    
125    }