View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.comparators;
18  
19  import java.io.Serializable;
20  import java.util.Comparator;
21  
22  import org.apache.commons.collections4.ComparatorUtils;
23  
24  /**
25   * Reverses the order of another comparator by reversing the arguments
26   * to its {@link #compare(Object, Object) compare} method.
27   *
28   * @param <E> the type of objects compared by this comparator
29   *
30   * @since 2.0
31   * @see java.util.Collections#reverseOrder()
32   */
33  public class ReverseComparator<E> implements Comparator<E>, Serializable {
34  
35      /** Serialization version from Collections 2.0. */
36      private static final long serialVersionUID = 2858887242028539265L;
37  
38      /** The comparator being decorated. */
39      private final Comparator<? super E> comparator;
40  
41      /**
42       * Creates a comparator that compares objects based on the inverse of their
43       * natural ordering.  Using this Constructor will create a ReverseComparator
44       * that is functionally identical to the Comparator returned by
45       * java.util.Collections.<b>reverseOrder()</b>.
46       *
47       * @see java.util.Collections#reverseOrder()
48       */
49      public ReverseComparator() {
50          this(null);
51      }
52  
53      /**
54       * Creates a comparator that inverts the comparison
55       * of the given comparator.  If you pass in {@code null},
56       * the ReverseComparator defaults to reversing the
57       * natural order, as per {@link java.util.Collections#reverseOrder()}.
58       *
59       * @param comparator Comparator to reverse
60       */
61      public ReverseComparator(final Comparator<? super E> comparator) {
62          this.comparator = comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : comparator;
63      }
64  
65      /**
66       * Compares two objects in reverse order.
67       *
68       * @param obj1  the first object to compare
69       * @param obj2  the second object to compare
70       * @return negative if obj1 is less, positive if greater, zero if equal
71       */
72      @Override
73      public int compare(final E obj1, final E obj2) {
74          return comparator.compare(obj2, obj1);
75      }
76  
77      /**
78       * Returns {@code true} iff <i>that</i> Object is
79       * a {@link Comparator} whose ordering is known to be
80       * equivalent to mine.
81       * <p>
82       * This implementation returns {@code true}
83       * iff {@code <i>object</i>.{@link Object#getClass() getClass()}}
84       * equals {@code this.getClass()}, and the underlying
85       * comparators are equal.
86       * Subclasses may want to override this behavior to remain consistent
87       * with the {@link Comparator#equals(Object) equals} contract.
88       *
89       * @param object  the object to compare to
90       * @return true if equal
91       * @since 3.0
92       */
93      @Override
94      public boolean equals(final Object object) {
95          if (this == object) {
96              return true;
97          }
98          if (null == object) {
99              return false;
100         }
101         if (object.getClass().equals(this.getClass())) {
102             final ReverseComparator<?> thatrc = (ReverseComparator<?>) object;
103             return comparator.equals(thatrc.comparator);
104         }
105         return false;
106     }
107 
108     /**
109      * Implement a hash code for this comparator that is consistent with
110      * {@link #equals(Object) equals}.
111      *
112      * @return a suitable hash code
113      * @since 3.0
114      */
115     @Override
116     public int hashCode() {
117         return "ReverseComparator".hashCode() ^ comparator.hashCode();
118     }
119 
120 }