org.glassfish.jersey.internal.guava.Ordering Maven / Gradle / Ivy
Show all versions of jaxrs-ri Show documentation
/*
* 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}.
*
*
The common ways to get an instance of {@code Ordering} are:
*
*
* - Subclass it and implement {@link #compare} instead of implementing
* {@link Comparator} directly
*
- Pass a pre-existing {@link Comparator} instance to {@link
* #from(Comparator)}
*
- Use the natural ordering, {@link Ordering#natural}
*
*
*
Then you can use the chaining methods to get an altered version of
* that {@code Ordering}, including:
*
*
* - {@link #reverse}
*
- {@link #compound(Comparator)}
*
- {@link #onResultOf(Function)}
*
- {@link #nullsFirst} / {@link #nullsLast}
*
*
*
Finally, use the resulting {@code Ordering} anywhere a {@link Comparator}
* is required, or use any of its special operations, such as:
*
*
* - {@link #immutableSortedCopy}
*
- {@link #isOrdered} / {@link #isStrictlyOrdered}
*
- {@link #min} / {@link #max}
*
*
*
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.
*
*
See the Guava User Guide article on
* {@code Ordering}.
*
* @author Jesse Wilson
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
public abstract class Ordering implements Comparator {
// 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.
*
*
The type specification is {@code }, instead of
* the technically correct {@code >}, to
* support legacy types from before Java 5.
*/
@SuppressWarnings("unchecked") // TODO(kevinb): right way to explain this??
public static Ordering natural() {
return (Ordering) NaturalOrdering.INSTANCE;
}
/**
* Returns an ordering based on an existing comparator instance. Note
* that it is unnecessary to create a new 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 Ordering from(Comparator comparator) {
return (comparator instanceof Ordering)
? (Ordering) comparator
: new ComparatorOrdering(comparator);
}
/**
* Returns the reverse of this ordering; the {@code Ordering} equivalent to
* {@link Collections#reverseOrder(Comparator)}.
*/
// type parameter lets us avoid the extra in statements like:
// Ordering o = Ordering.natural().reverse();
public Ordering reverse() {
return new ReverseOrdering(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 lets us avoid the extra in statements like:
// Ordering o = Ordering.natural().nullsFirst();
Ordering nullsFirst() {
return new NullsFirstOrdering(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 lets us avoid the extra in statements like:
// Ordering o = Ordering.natural().nullsLast();
Ordering nullsLast() {
return new NullsLastOrdering(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 mutually
* comparable under this ordering.
* @since 11.0
*/
E min(Iterator 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 mutually
* comparable under this ordering.
*/
E min(Iterable 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.
*
*
Implementation note: 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 mutually
* comparable under this ordering.
*/
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 mutually
* comparable under this ordering.
*/
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 mutually
* comparable under this ordering.
* @since 11.0
*/
E max(Iterator 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 mutually
* comparable under this ordering.
*/
E max(Iterable 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.
*
*
Implementation note: 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 mutually
* comparable under this ordering.
*/
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 mutually
* comparable under this ordering.
*/
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;
}
}