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     * A {@link Comparator Comparator} that compares 
024     * {@link Comparable Comparable} objects.
025     * <p />
026     * This Comparator is useful, for example,
027     * for enforcing the natural order in custom implementations
028     * of SortedSet and SortedMap.
029     * <p />
030     * Note: In the 2.0 and 2.1 releases of Commons Collections, 
031     * this class would throw a {@link ClassCastException} if
032     * either of the arguments to {@link #compare(Object, Object) compare}
033     * were <code>null</code>, not {@link Comparable Comparable},
034     * or for which {@link Comparable#compareTo(Object) compareTo} gave
035     * inconsistent results.  This is no longer the case.  See
036     * {@link #compare(Object, Object) compare} for details.
037     *
038     * @since Commons Collections 2.0
039     * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
040     *
041     * @author Henri Yandell
042     *
043     * @see java.util.Collections#reverseOrder()
044     */
045    public class ComparableComparator implements Comparator, Serializable {
046    
047        /** Serialization version. */
048        private static final long serialVersionUID=-291439688585137865L;
049    
050        /** The singleton instance. */
051        private static final ComparableComparator instance = new ComparableComparator();
052    
053        //-----------------------------------------------------------------------
054        /**
055         * Gets the singleton instance of a ComparableComparator.
056         * <p>
057         * Developers are encouraged to use the comparator returned from this method
058         * instead of constructing a new instance to reduce allocation and GC overhead
059         * when multiple comparable comparators may be used in the same VM.
060         * 
061         * @return the singleton ComparableComparator
062         */
063        public static ComparableComparator getInstance() {
064            return instance;
065        }
066    
067        //-----------------------------------------------------------------------
068        /**
069         * Constructor whose use should be avoided.
070         * <p>
071         * Please use the {@link #getInstance()} method whenever possible.
072         */
073        public ComparableComparator() {
074            super();
075        }
076    
077        //-----------------------------------------------------------------------
078        /**
079         * Compare the two {@link Comparable Comparable} arguments.
080         * This method is equivalent to:
081         * <pre>((Comparable)obj1).compareTo(obj2)</pre>
082         * 
083         * @param obj1  the first object to compare
084         * @param obj2  the second object to compare
085         * @return negative if obj1 is less, positive if greater, zero if equal
086         * @throws NullPointerException when <i>obj1</i> is <code>null</code>, 
087         *         or when <code>((Comparable)obj1).compareTo(obj2)</code> does
088         * @throws ClassCastException when <i>obj1</i> is not a <code>Comparable</code>,
089         *         or when <code>((Comparable)obj1).compareTo(obj2)</code> does
090         */
091        public int compare(Object obj1, Object obj2) {
092            return ((Comparable)obj1).compareTo(obj2);
093        }
094    
095        //-----------------------------------------------------------------------
096        /**
097         * Implement a hash code for this comparator that is consistent with
098         * {@link #equals(Object) equals}.
099         *
100         * @return a hash code for this comparator.
101         * @since Commons Collections 3.0
102         */
103        public int hashCode() {
104            return "ComparableComparator".hashCode();
105        }
106    
107        /**
108         * Returns <code>true</code> iff <i>that</i> Object is 
109         * is a {@link Comparator Comparator} whose ordering is 
110         * known to be equivalent to mine.
111         * <p>
112         * This implementation returns <code>true</code>
113         * iff <code><i>object</i>.{@link Object#getClass() getClass()}</code>
114         * equals <code>this.getClass()</code>.
115         * Subclasses may want to override this behavior to remain consistent
116         * with the {@link Comparator#equals(Object)} contract.
117         * 
118         * @param object  the object to compare with
119         * @return true if equal
120         * @since Commons Collections 3.0
121         */
122        public boolean equals(Object object) {
123            return (this == object) || 
124                   ((null != object) && (object.getClass().equals(this.getClass())));
125        }
126    
127    }