--- a/jdk/src/share/classes/java/util/Comparator.java Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparator.java Tue Jun 11 13:41:38 2013 -0700
@@ -25,10 +25,12 @@
package java.util;
+import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
+import java.util.Comparators;
/**
* A comparison function, which imposes a <i>total ordering</i> on some
@@ -175,88 +177,357 @@
* Returns a comparator that imposes the reverse ordering of this
* comparator.
*
- * @return A comparator that imposes the reverse ordering of this
+ * @return a comparator that imposes the reverse ordering of this
* comparator.
* @since 1.8
*/
- default Comparator<T> reverseOrder() {
+ default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
/**
- * Constructs a lexicographic order comparator with another comparator.
- * For example, a {@code Comparator<Person> byLastName} can be composed
- * with another {@code Comparator<Person> byFirstName}, then {@code
- * byLastName.thenComparing(byFirstName)} creates a {@code
- * Comparator<Person>} which sorts by last name, and for equal last names
- * sorts by first name.
+ * Returns a lexicographic-order comparator with another comparator.
+ * If this {@code Comparator} considers two elements equal, i.e.
+ * {@code compare(a, b) == 0}, {@code other} is used to determine the order.
+ *
+ * <p>The returned comparator is serializable if the specified comparator
+ * is also serializable.
*
- * @param other the other comparator used when equals on this.
+ * @apiNote
+ * For example, to sort a collection of {@code String} based on the length
+ * and then case-insensitive natural ordering, the comparator can be
+ * composed using following code,
+ *
+ * <pre>{@code
+ * Comparator<String> cmp = Comparator.comparing(String::length)
+ * .thenComparing(String.CASE_INSENSITIVE_ORDER);
+ * }</pre>
+ *
+ * @param other the other comparator to be used when this comparator
+ * compares two objects that are equal.
+ * @return a lexicographic-order comparator composed of this and then the
+ * other comparator
* @throws NullPointerException if the argument is null.
* @since 1.8
*/
default Comparator<T> thenComparing(Comparator<? super T> other) {
- return Comparators.compose(this, other);
+ Objects.requireNonNull(other);
+ return (Comparator<T> & Serializable) (c1, c2) -> {
+ int res = compare(c1, c2);
+ return (res != 0) ? res : other.compare(c1, c2);
+ };
+ }
+
+ /**
+ * Returns a lexicographic-order comparator with a function that
+ * extracts a key to be compared with the given {@code Comparator}.
+ *
+ * @implSpec This default implementation behaves as if {@code
+ * thenComparing(comparing(keyExtractor, cmp))}.
+ *
+ * @param <U> the type of the sort key
+ * @param keyExtractor the function used to extract the sort key
+ * @param keyComparator the {@code Comparator} used to compare the sort key
+ * @return a lexicographic-order comparator composed of this comparator
+ * and then comparing on the key extracted by the keyExtractor function
+ * @throws NullPointerException if the argument is null.
+ * @see #comparing(Function, Comparator)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default <U extends Comparable<? super U>> Comparator<T> thenComparing(
+ Function<? super T, ? extends U> keyExtractor,
+ Comparator<? super U> keyComparator)
+ {
+ return thenComparing(comparing(keyExtractor, keyComparator));
}
/**
- * Constructs a lexicographic order comparator with a function that
- * extracts a {@code Comparable} key. This default implementation calls
- * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ * Returns a lexicographic-order comparator with a function that
+ * extracts a {@code Comparable} sort key.
+ *
+ * @implSpec This default implementation behaves as if {@code
+ * thenComparing(comparing(keyExtractor))}.
*
- * @param <U> the {@link Comparable} type for comparison
- * @param keyExtractor the function used to extract the {@link Comparable} sort key
+ * @param <U> the type of the {@link Comparable} sort key
+ * @param keyExtractor the function used to extract the {@link
+ * Comparable} sort key
+ * @return a lexicographic-order comparator composed of this and then the
+ * {@link Comparable} sort key.
* @throws NullPointerException if the argument is null.
- * @see Comparators#comparing(Function)
+ * @see #comparing(Function)
* @see #thenComparing(Comparator)
* @since 1.8
*/
- default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor) {
- return thenComparing(Comparators.comparing(keyExtractor));
+ default <U extends Comparable<? super U>> Comparator<T> thenComparing(
+ Function<? super T, ? extends U> keyExtractor)
+ {
+ return thenComparing(comparing(keyExtractor));
}
/**
- * Constructs a lexicographic order comparator with a function that
- * extracts a {@code int} value. This default implementation calls {@code
- * thenComparing(this, Comparators.comparing(keyExtractor))}.
+ * Returns a lexicographic-order comparator with a function that
+ * extracts a {@code int} sort key.
+ *
+ * @implSpec This default implementation behaves as if {@code
+ * thenComparing(comparing(keyExtractor))}.
*
- * @param keyExtractor the function used to extract the integer value
+ * @param keyExtractor the function used to extract the integer sort key
+ * @return a lexicographic-order comparator composed of this and then the
+ * {@code int} sort key
* @throws NullPointerException if the argument is null.
- * @see Comparators#comparing(ToIntFunction)
+ * @see #comparing(ToIntFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
- return thenComparing(Comparators.comparing(keyExtractor));
+ return thenComparing(comparing(keyExtractor));
}
/**
- * Constructs a lexicographic order comparator with a function that
- * extracts a {@code long} value. This default implementation calls
- * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ * Returns a lexicographic-order comparator with a function that
+ * extracts a {@code long} sort key.
+ *
+ * @implSpec This default implementation behaves as if {@code
+ * thenComparing(comparing(keyExtractor))}.
*
- * @param keyExtractor the function used to extract the long value
+ * @param keyExtractor the function used to extract the long sort key
+ * @return a lexicographic-order comparator composed of this and then the
+ * {@code long} sort key
* @throws NullPointerException if the argument is null.
- * @see Comparators#comparing(ToLongFunction)
+ * @see #comparing(ToLongFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
- return thenComparing(Comparators.comparing(keyExtractor));
+ return thenComparing(comparing(keyExtractor));
}
/**
- * Constructs a lexicographic order comparator with a function that
- * extracts a {@code double} value. This default implementation calls
- * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ * Returns a lexicographic-order comparator with a function that
+ * extracts a {@code double} sort key.
+ *
+ * @implSpec This default implementation behaves as if {@code
+ * thenComparing(comparing(keyExtractor))}.
*
- * @param keyExtractor the function used to extract the double value
+ * @param keyExtractor the function used to extract the double sort key
+ * @return a lexicographic-order comparator composed of this and then the
+ * {@code double} sort key
* @throws NullPointerException if the argument is null.
- * @see Comparators#comparing(ToDoubleFunction)
+ * @see #comparing(ToDoubleFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
- return thenComparing(Comparators.comparing(keyExtractor));
+ return thenComparing(comparing(keyExtractor));
+ }
+
+ /**
+ * Returns a comparator that imposes the reverse of the <em>natural
+ * ordering</em>.
+ *
+ * <p>The returned comparator is serializable and throws {@link
+ * NullPointerException} when comparing {@code null}.
+ *
+ * @param <T> the {@link Comparable} type of element to be compared
+ * @return a comparator that imposes the reverse of the <i>natural
+ * ordering</i> on {@code Comparable} objects.
+ * @see Comparable
+ * @since 1.8
+ */
+ public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
+ return Collections.reverseOrder();
+ }
+
+ /**
+ * Returns a comparator that compares {@link Comparable} objects in natural
+ * order.
+ *
+ * <p>The returned comparator is serializable and throws {@link
+ * NullPointerException} when comparing {@code null}.
+ *
+ * @param <T> the {@link Comparable} type of element to be compared
+ * @return a comparator that imposes the <i>natural ordering</i> on {@code
+ * Comparable} objects.
+ * @see Comparable
+ * @since 1.8
+ */
+ public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
+ return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
+ }
+
+ /**
+ * Returns a null-friendly comparator that considers {@code null} to be
+ * less than non-null. When both are {@code null}, they are considered
+ * equal. If both are non-null, the specified {@code Comparator} is used
+ * to determine the order. If the specified comparator is {@code null},
+ * then the returned comparator considers all non-null values to be equal.
+ *
+ * <p>The returned comparator is serializable if the specified comparator
+ * is serializable.
+ *
+ * @param <T> the type of the elements to be compared
+ * @param comparator a {@code Comparator} for comparing non-null values
+ * @return a comparator that considers {@code null} to be less than
+ * non-null, and compares non-null objects with the supplied
+ * {@code Comparator}.
+ * @since 1.8
+ */
+ public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
+ return new Comparators.NullComparator(true, comparator);
+ }
+
+ /**
+ * Returns a null-friendly comparator that considers {@code null} to be
+ * greater than non-null. When both are {@code null}, they are considered
+ * equal. If both are non-null, the specified {@code Comparator} is used
+ * to determine the order. If the specified comparator is {@code null},
+ * then the returned comparator considers all non-null values to be equal.
+ *
+ * <p>The returned comparator is serializable if the specified comparator
+ * is serializable.
+ *
+ * @param <T> the type of the elements to be compared
+ * @param comparator a {@code Comparator} for comparing non-null values
+ * @return a comparator that considers {@code null} to be greater than
+ * non-null, and compares non-null objects with the supplied
+ * {@code Comparator}.
+ * @since 1.8
+ */
+ public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
+ return new Comparators.NullComparator(false, comparator);
+ }
+
+ /**
+ * Accepts a function that extracts a sort key from a type {@code T}, and
+ * returns a {@code Comparator<T>} that compares by that sort key using
+ * the specified {@link Comparator}.
+ *
+ * <p>The returned comparator is serializable if the specified function
+ * and comparator are both serializable.
+ *
+ * @apiNote
+ * For example, to obtain a {@code Comparator} that compares {@code
+ * Person} objects by their last name ignoring case differences,
+ *
+ * <pre>{@code
+ * Comparator<Person> cmp = Comparator.comparing(
+ * Person::getLastName,
+ * String.CASE_INSENSITIVE_ORDER);
+ * }</pre>
+ *
+ * @param <T> the type of element to be compared
+ * @param <U> the type of the sort key
+ * @param keyExtractor the function used to extract the sort key
+ * @param keyComparator the {@code Comparator} used to compare the sort key
+ * @return a comparator that compares by an extracted key using the
+ * specified {@code Comparator}
+ * @throws NullPointerException if either argument is null
+ * @since 1.8
+ */
+ public static <T, U> Comparator<T> comparing(
+ Function<? super T, ? extends U> keyExtractor,
+ Comparator<? super U> keyComparator)
+ {
+ Objects.requireNonNull(keyExtractor);
+ Objects.requireNonNull(keyComparator);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
+ keyExtractor.apply(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@link java.lang.Comparable
+ * Comparable} sort key from a type {@code T}, and returns a {@code
+ * Comparator<T>} that compares by that sort key.
+ *
+ * <p>The returned comparator is serializable if the specified function
+ * is also serializable.
+ *
+ * @apiNote
+ * For example, to obtain a {@code Comparator} that compares {@code
+ * Person} objects by their last name,
+ *
+ * <pre>{@code
+ * Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);
+ * }</pre>
+ *
+ * @param <T> the type of element to be compared
+ * @param <U> the type of the {@code Comparable} sort key
+ * @param keyExtractor the function used to extract the {@link
+ * Comparable} sort key
+ * @return a comparator that compares by an extracted key
+ * @throws NullPointerException if the argument is null
+ * @since 1.8
+ */
+ public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
+ Function<? super T, ? extends U> keyExtractor)
+ {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
+ }
+
+ /**
+ * Accepts a function that extracts an {@code int} sort key from a type
+ * {@code T}, and returns a {@code Comparator<T>} that compares by that
+ * sort key.
+ *
+ * <p>The returned comparator is serializable if the specified function
+ * is also serializable.
+ *
+ * @param <T> the type of element to be compared
+ * @param keyExtractor the function used to extract the integer sort key
+ * @return a comparator that compares by an extracted key
+ * @see #comparing(Function)
+ * @throws NullPointerException if the argument is null
+ * @since 1.8
+ */
+ public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@code long} sort key from a type
+ * {@code T}, and returns a {@code Comparator<T>} that compares by that
+ * sort key.
+ *
+ * <p>The returned comparator is serializable if the specified function is
+ * also serializable.
+ *
+ * @param <T> the type of element to be compared
+ * @param keyExtractor the function used to extract the long sort key
+ * @return a comparator that compares by an extracted key
+ * @see #comparing(Function)
+ * @throws NullPointerException if the argument is null
+ * @since 1.8
+ */
+ public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@code double} sort key from a type
+ * {@code T}, and returns a {@code Comparator<T>} that compares by that
+ * sort key.
+ *
+ * <p>The returned comparator is serializable if the specified function
+ * is also serializable.
+ *
+ * @param <T> the type of element to be compared
+ * @param keyExtractor the function used to extract the double sort key
+ * @return a comparator that compares by an extracted key
+ * @see #comparing(Function)
+ * @throws NullPointerException if the argument is null
+ * @since 1.8
+ */
+ public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
}
}