001    /*
002     * Copyright 2009-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-2016 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.util;
022    
023    
024    
025    import java.io.Serializable;
026    import java.util.Comparator;
027    
028    
029    
030    /**
031     * This class provides an implementation of a {@code Comparator} object that may
032     * be used to iterate through values in what would normally be considered
033     * reverse order.
034     *
035     * @param  <T>  The type of object to use with this comparator.
036     */
037    @NotMutable()
038    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
039    public final class ReverseComparator<T>
040           implements Comparator<T>, Serializable
041    {
042      /**
043       * The serial version UID for this serializable class.
044       */
045      private static final long serialVersionUID = -4615537960027681276L;
046    
047    
048    
049      // The comparator that will be used to make the underlying determination.
050      private final Comparator<T> baseComparator;
051    
052    
053    
054      /**
055       * Creates a new comparator that will sort items in reverse order.  The
056       * generic type for this class must implement the {@link Comparable}
057       * interface.
058       */
059      public ReverseComparator()
060      {
061        baseComparator = null;
062      }
063    
064    
065    
066      /**
067       * Creates a new comparator that will sort items in the reverse order that
068       * they would be normally sorted using the given comparator.
069       *
070       * @param  baseComparator  The base comparator that will be used to make the
071       *                         determination.
072       */
073      public ReverseComparator(final Comparator<T> baseComparator)
074      {
075        this.baseComparator = baseComparator;
076      }
077    
078    
079    
080      /**
081       * Compares the provided objects to determine their relative order in a
082       * sorted list.
083       *
084       * @param  o1  The first object to compare.
085       * @param  o2  The second object to compare.
086       *
087       * @return  A negative integer if the first object should be ordered before
088       *          the second, a positive integer if the first object should be
089       *          ordered after the second, or zero if there is no difference in
090       *          their relative orders.
091       */
092      @SuppressWarnings("unchecked")
093      public int compare(final T o1, final T o2)
094      {
095        final int baseValue;
096        if (baseComparator == null)
097        {
098          baseValue = ((Comparable<? super T>) o1).compareTo(o2);
099        }
100        else
101        {
102          baseValue = baseComparator.compare(o1, o2);
103        }
104    
105        if (baseValue < 0)
106        {
107          return 1;
108        }
109        else if (baseValue > 0)
110        {
111          return -1;
112        }
113        else
114        {
115          return 0;
116        }
117      }
118    
119    
120    
121      /**
122       * Retrieves a hash code for this class.
123       *
124       * @return  A hash code for this class.
125       */
126      @Override()
127      public int hashCode()
128      {
129        if (baseComparator == null)
130        {
131          return 0;
132        }
133        else
134        {
135          return baseComparator.hashCode();
136        }
137      }
138    
139    
140    
141      /**
142       * Indicates whether the provided object may be considered equal to this
143       * comparator.
144       *
145       * @param  o  The object for which to make the determination.
146       *
147       * @return  {@code true} if the provided object may be considered equal to
148       *          this comparator, or {@code false} if not.
149       */
150      @Override()
151      @SuppressWarnings("unchecked")
152      public boolean equals(final Object o)
153      {
154        if (o == null)
155        {
156          return false;
157        }
158    
159        if (o == this)
160        {
161          return true;
162        }
163    
164        if (! (o.getClass().equals(ReverseComparator.class)))
165        {
166          return false;
167        }
168    
169        final ReverseComparator<T> c = (ReverseComparator<T>) o;
170        if (baseComparator == null)
171        {
172          return (c.baseComparator == null);
173        }
174        else
175        {
176          return baseComparator.equals(c.baseComparator);
177        }
178      }
179    }