001/*
002 * Copyright 2009-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2009-2019 Ping Identity Corporation
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  @Override()
094  public int compare(final T o1, final T o2)
095  {
096    final int baseValue;
097    if (baseComparator == null)
098    {
099      baseValue = ((Comparable<? super T>) o1).compareTo(o2);
100    }
101    else
102    {
103      baseValue = baseComparator.compare(o1, o2);
104    }
105
106    if (baseValue < 0)
107    {
108      return 1;
109    }
110    else if (baseValue > 0)
111    {
112      return -1;
113    }
114    else
115    {
116      return 0;
117    }
118  }
119
120
121
122  /**
123   * Retrieves a hash code for this class.
124   *
125   * @return  A hash code for this class.
126   */
127  @Override()
128  public int hashCode()
129  {
130    if (baseComparator == null)
131    {
132      return 0;
133    }
134    else
135    {
136      return baseComparator.hashCode();
137    }
138  }
139
140
141
142  /**
143   * Indicates whether the provided object may be considered equal to this
144   * comparator.
145   *
146   * @param  o  The object for which to make the determination.
147   *
148   * @return  {@code true} if the provided object may be considered equal to
149   *          this comparator, or {@code false} if not.
150   */
151  @Override()
152  @SuppressWarnings("unchecked")
153  public boolean equals(final Object o)
154  {
155    if (o == null)
156    {
157      return false;
158    }
159
160    if (o == this)
161    {
162      return true;
163    }
164
165    if (! (o.getClass().equals(ReverseComparator.class)))
166    {
167      return false;
168    }
169
170    final ReverseComparator<T> c = (ReverseComparator<T>) o;
171    if (baseComparator == null)
172    {
173      return (c.baseComparator == null);
174    }
175    else
176    {
177      return baseComparator.equals(c.baseComparator);
178    }
179  }
180}