/*
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.glassfish.jersey.internal.guava;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;
/**
* A comparator, with additional methods to support common operations. This is
* an "enriched" version of {@code Comparator}, in the same sense that {@link
* FluentIterable} is an enriched {@link Iterable}.
* <p>
* <p>The common ways to get an instance of {@code Ordering} are:
* <p>
* <ul>
* <li>Subclass it and implement {@link #compare} instead of implementing
* {@link Comparator} directly
* <li>Pass a <i>pre-existing</i> {@link Comparator} instance to {@link
* #from(Comparator)}
* <li>Use the natural ordering, {@link Ordering#natural}
* </ul>
* <p>
* <p>Then you can use the <i>chaining</i> methods to get an altered version of
* that {@code Ordering}, including:
* <p>
* <ul>
* <li>{@link #reverse}
* <li>{@link #compound(Comparator)}
* <li>{@link #onResultOf(Function)}
* <li>{@link #nullsFirst} / {@link #nullsLast}
* </ul>
* <p>
* <p>Finally, use the resulting {@code Ordering} anywhere a {@link Comparator}
* is required, or use any of its special operations, such as:</p>
* <p>
* <ul>
* <li>{@link #immutableSortedCopy}
* <li>{@link #isOrdered} / {@link #isStrictlyOrdered}
* <li>{@link #min} / {@link #max}
* </ul>
* <p>
* <p>Except as noted, the orderings returned by the factory methods of this
* class are serializable if and only if the provided instances that back them
* are. For example, if {@code ordering} and {@code function} can themselves be
* serialized, then {@code ordering.onResultOf(function)} can as well.
* <p>
* <p>See the Guava User Guide article on <a href=
* "http://code.google.com/p/guava-libraries/wiki/OrderingExplained">
* {@code Ordering}</a>.
*
* @author Jesse Wilson
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
public abstract class Ordering<T> implements Comparator<T> {
// Natural order
// Never make these public
static final int LEFT_IS_GREATER = 1;
// Static factories
static final int RIGHT_IS_GREATER = -1;
/**
* Constructs a new instance of this class (only invokable by the subclass
* constructor, typically implicit).
*/
Ordering() {
}
// Instance-based factories (and any static equivalents)
/**
* Returns a serializable ordering that uses the natural order of the values.
* The ordering throws a {@link NullPointerException} when passed a null
* parameter.
* <p>
* <p>The type specification is {@code <C extends Comparable>}, instead of
* the technically correct {@code <C extends Comparable<? super C>>}, to
* support legacy types from before Java 5.
*/
@SuppressWarnings("unchecked") // TODO(kevinb): right way to explain this??
public static <C extends Comparable> Ordering<C> natural() {
return (Ordering<C>) NaturalOrdering.INSTANCE;
}
/**
* Returns an ordering based on an <i>existing</i> comparator instance. Note
* that it is unnecessary to create a <i>new</i> anonymous inner class
* implementing {@code Comparator} just to pass it in here. Instead, simply
* subclass {@code Ordering} and implement its {@code compare} method
* directly.
*
* @param comparator the comparator that defines the order
* @return comparator itself if it is already an {@code Ordering}; otherwise
* an ordering that wraps that comparator
*/
public static <T> Ordering<T> from(Comparator<T> comparator) {
return (comparator instanceof Ordering)
? (Ordering<T>) comparator
: new ComparatorOrdering<T>(comparator);
}
/**
* Returns the reverse of this ordering; the {@code Ordering} equivalent to
* {@link Collections#reverseOrder(Comparator)}.
*/
// type parameter <S> lets us avoid the extra <String> in statements like:
// Ordering<String> o = Ordering.<String>natural().reverse();
public <S extends T> Ordering<S> reverse() {
return new ReverseOrdering<S>(this);
}
/**
* Returns an ordering that treats {@code null} as less than all other values
* and uses {@code this} to compare non-null values.
*/
// type parameter <S> lets us avoid the extra <String> in statements like:
// Ordering<String> o = Ordering.<String>natural().nullsFirst();
<S extends T> Ordering<S> nullsFirst() {
return new NullsFirstOrdering<S>(this);
}
/**
* Returns an ordering that treats {@code null} as greater than all other
* values and uses this ordering to compare non-null values.
*/
// type parameter <S> lets us avoid the extra <String> in statements like:
// Ordering<String> o = Ordering.<String>natural().nullsLast();
<S extends T> Ordering<S> nullsLast() {
return new NullsLastOrdering<S>(this);
}
// Regular instance methods
// Override to add @Nullable
@Override
public abstract int compare(T left, T right);
/**
* Returns the least of the specified values according to this ordering. If
* there are multiple least values, the first of those is returned. The
* iterator will be left exhausted: its {@code hasNext()} method will return
* {@code false}.
*
* @param iterator the iterator whose minimum element is to be determined
* @throws NoSuchElementException if {@code iterator} is empty
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
* @since 11.0
*/
<E extends T> E min(Iterator<E> iterator) {
// let this throw NoSuchElementException as necessary
E minSoFar = iterator.next();
while (iterator.hasNext()) {
minSoFar = min(minSoFar, iterator.next());
}
return minSoFar;
}
/**
* Returns the least of the specified values according to this ordering. If
* there are multiple least values, the first of those is returned.
*
* @param iterable the iterable whose minimum element is to be determined
* @throws NoSuchElementException if {@code iterable} is empty
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
*/
<E extends T> E min(Iterable<E> iterable) {
return min(iterable.iterator());
}
/**
* Returns the lesser of the two values according to this ordering. If the
* values compare as 0, the first is returned.
* <p>
* <p><b>Implementation note:</b> this method is invoked by the default
* implementations of the other {@code min} overloads, so overriding it will
* affect their behavior.
*
* @param a value to compare, returned if less than or equal to b.
* @param b value to compare.
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
*/
<E extends T> E min(E a, E b) {
return (compare(a, b) <= 0) ? a : b;
}
/**
* Returns the least of the specified values according to this ordering. If
* there are multiple least values, the first of those is returned.
*
* @param a value to compare, returned if less than or equal to the rest.
* @param b value to compare
* @param c value to compare
* @param rest values to compare
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
*/
<E extends T> E min(
E a, E b, E c, E... rest) {
E minSoFar = min(min(a, b), c);
for (E r : rest) {
minSoFar = min(minSoFar, r);
}
return minSoFar;
}
/**
* Returns the greatest of the specified values according to this ordering. If
* there are multiple greatest values, the first of those is returned. The
* iterator will be left exhausted: its {@code hasNext()} method will return
* {@code false}.
*
* @param iterator the iterator whose maximum element is to be determined
* @throws NoSuchElementException if {@code iterator} is empty
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
* @since 11.0
*/
<E extends T> E max(Iterator<E> iterator) {
// let this throw NoSuchElementException as necessary
E maxSoFar = iterator.next();
while (iterator.hasNext()) {
maxSoFar = max(maxSoFar, iterator.next());
}
return maxSoFar;
}
/**
* Returns the greatest of the specified values according to this ordering. If
* there are multiple greatest values, the first of those is returned.
*
* @param iterable the iterable whose maximum element is to be determined
* @throws NoSuchElementException if {@code iterable} is empty
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
*/
<E extends T> E max(Iterable<E> iterable) {
return max(iterable.iterator());
}
/**
* Returns the greater of the two values according to this ordering. If the
* values compare as 0, the first is returned.
* <p>
* <p><b>Implementation note:</b> this method is invoked by the default
* implementations of the other {@code max} overloads, so overriding it will
* affect their behavior.
*
* @param a value to compare, returned if greater than or equal to b.
* @param b value to compare.
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
*/
<E extends T> E max(E a, E b) {
return (compare(a, b) >= 0) ? a : b;
}
/**
* Returns the greatest of the specified values according to this ordering. If
* there are multiple greatest values, the first of those is returned.
*
* @param a value to compare, returned if greater than or equal to the rest.
* @param b value to compare
* @param c value to compare
* @param rest values to compare
* @throws ClassCastException if the parameters are not <i>mutually
* comparable</i> under this ordering.
*/
<E extends T> E max(
E a, E b, E c, E... rest) {
E maxSoFar = max(max(a, b), c);
for (E r : rest) {
maxSoFar = max(maxSoFar, r);
}
return maxSoFar;
}
}