001/*
002 * Copyright 2009-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2009-2014 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 */
021package com.unboundid.util;
022
023
024
025import java.io.Serializable;
026import 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)
039public 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}