--- a/jdk/src/share/classes/java/util/Comparators.java Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparators.java Tue Jun 11 13:41:38 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,16 +32,9 @@
import java.util.function.ToLongFunction;
/**
- * This class consists of {@code static} utility methods for comparators. Mostly
- * factory method that returns a {@link Comparator}.
- *
- * <p> Unless otherwise noted, passing a {@code null} argument to a method in
- * this class will cause a {@link NullPointerException} to be thrown.
- *
- * @see Comparator
- * @since 1.8
+ * Package private supporting class for {@link Comparator}.
*/
-public class Comparators {
+class Comparators {
private Comparators() {
throw new AssertionError("no instances");
}
@@ -51,231 +44,55 @@
*
* @see Comparable
*/
- private enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
+ enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
INSTANCE;
@Override
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c1.compareTo(c2);
}
- }
- /**
- * Returns a comparator that imposes the reverse of the <em>natural
- * ordering</em>.
- *
- * <p>The returned comparator is serializable.
- *
- * @param <T> {@link Comparable} type
- *
- * @return A comparator that imposes the reverse of the <i>natural
- * ordering</i> on a collection of objects that implement
- * the {@link Comparable} interface.
- * @see Comparable
- */
- public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
- return Collections.reverseOrder();
- }
-
- /**
- * Returns a comparator that imposes the reverse ordering of the specified
- * {@link Comparator}.
- *
- * <p>The returned comparator is serializable (assuming the specified
- * comparator is also serializable).
- *
- * @param <T> the element type to be compared
- * @param cmp a comparator whose ordering is to be reversed by the returned
- * comparator
- * @return A comparator that imposes the reverse ordering of the
- * specified comparator.
- */
- public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
- Objects.requireNonNull(cmp);
- return Collections.reverseOrder(cmp);
- }
-
- /**
- * Gets a comparator compares {@link Comparable} type in natural order.
- *
- * @param <T> {@link Comparable} type
- */
- public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
- return (Comparator<T>) NaturalOrderComparator.INSTANCE;
- }
-
- /**
- * Gets a comparator compares {@link Map.Entry} in natural order on key.
- *
- * @param <K> {@link Comparable} key type
- * @param <V> value type
- */
- public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> naturalOrderKeys() {
- return (Comparator<Map.Entry<K, V>> & Serializable)
- (c1, c2) -> c1.getKey().compareTo(c2.getKey());
- }
-
- /**
- * Gets a comparator compares {@link Map.Entry} in natural order on value.
- *
- * @param <K> key type
- * @param <V> {@link Comparable} value type
- */
- public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> naturalOrderValues() {
- return (Comparator<Map.Entry<K, V>> & Serializable)
- (c1, c2) -> c1.getValue().compareTo(c2.getValue());
- }
-
- /**
- * Gets a comparator compares {@link Map.Entry} by key using the given
- * {@link Comparator}.
- *
- * <p>The returned comparator is serializable assuming the specified
- * comparators are also serializable.
- *
- * @param <K> key type
- * @param <V> value type
- * @param cmp the key {@link Comparator}
- */
- public static <K, V> Comparator<Map.Entry<K, V>> byKey(Comparator<? super K> cmp) {
- Objects.requireNonNull(cmp);
- return (Comparator<Map.Entry<K, V>> & Serializable)
- (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
- }
-
- /**
- * Gets a comparator compares {@link Map.Entry} by value using the given
- * {@link Comparator}.
- *
- * @param <K> key type
- * @param <V> value type
- * @param cmp the value {@link Comparator}
- */
- public static <K, V> Comparator<Map.Entry<K, V>> byValue(Comparator<? super V> cmp) {
- Objects.requireNonNull(cmp);
- return (Comparator<Map.Entry<K, V>> & Serializable)
- (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
+ @Override
+ public Comparator<Comparable<Object>> reversed() {
+ return Comparator.reverseOrder();
+ }
}
/**
- * 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. For example, if a class
- * {@code Person} has a {@code String}-valued getter {@code getLastName},
- * then {@code comparing(Person::getLastName)} would return a {@code
- * Comparator<Person>} that compares {@code Person} objects by their last
- * name.
- *
- * @param <T> the original element type
- * @param <U> the {@link Comparable} type for comparison
- * @param keyExtractor the function used to extract the {@link Comparable} sort key
+ * Null-friendly comparators
*/
- 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));
- }
+ final static class NullComparator<T> implements Comparator<T>, Serializable {
+ private static final long serialVersionUID = -7569533591570686392L;
+ private final boolean nullFirst;
+ // if null, non-null Ts are considered equal
+ private final Comparator<T> real;
- /**
- * Accepts a function that extracts an {@code int} value from a type {@code
- * T}, and returns a {@code Comparator<T>} that compares by that value.
- *
- * <p>The returned comparator is serializable assuming the specified
- * function is also serializable.
- *
- * @see #comparing(Function)
- * @param <T> the original element type
- * @param keyExtractor the function used to extract the integer value
- */
- 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} value from a type {@code
- * T}, and returns a {@code Comparator<T>} that compares by that value.
- *
- * <p>The returned comparator is serializable assuming the specified
- * function is also serializable.
- *
- * @see #comparing(Function)
- * @param <T> the original element type
- * @param keyExtractor the function used to extract the long value
- */
- 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));
- }
+ @SuppressWarnings("unchecked")
+ NullComparator(boolean nullFirst, Comparator<? super T> real) {
+ this.nullFirst = nullFirst;
+ this.real = (Comparator<T>) real;
+ }
- /**
- * Accepts a function that extracts a {@code double} value from a type
- * {@code T}, and returns a {@code Comparator<T>} that compares by that
- * value.
- *
- * <p>The returned comparator is serializable assuming the specified
- * function is also serializable.
- *
- * @see #comparing(Function)
- * @param <T> the original element type
- * @param keyExtractor the function used to extract the double value
- */
- 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));
- }
+ @Override
+ public int compare(T a, T b) {
+ if (a == null) {
+ return (b == null) ? 0 : (nullFirst ? -1 : 1);
+ } else if (b == null) {
+ return nullFirst ? 1: -1;
+ } else {
+ return (real == null) ? 0 : real.compare(a, b);
+ }
+ }
- /**
- * Constructs a lexicographic order from two {@link Comparator}s. For
- * example, if you have comparators {@code byLastName} and {@code
- * byFirstName}, each of type {@code Comparator<Person>}, then {@code
- * compose(byLastName, byFirstName)} creates a {@code Comparator<Person>}
- * which sorts by last name, and for equal last names sorts by first name.
- *
- * <p>The returned comparator is serializable assuming the specified
- * comparators are also serializable.
- *
- * @param <T> the element type to be compared
- * @param first the first comparator
- * @param second the secondary comparator used when equals on the first
- */
- public static<T> Comparator<T> compose(Comparator<? super T> first, Comparator<? super T> second) {
- Objects.requireNonNull(first);
- Objects.requireNonNull(second);
- return (Comparator<T> & Serializable) (c1, c2) -> {
- int res = first.compare(c1, c2);
- return (res != 0) ? res : second.compare(c1, c2);
- };
- }
+ @Override
+ public Comparator<T> thenComparing(Comparator<? super T> other) {
+ Objects.requireNonNull(other);
+ return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other));
+ }
- /**
- * Constructs a {@link BinaryOperator} which returns the lesser of two elements
- * according to the specified {@code Comparator}
- *
- * @param comparator A {@code Comparator} for comparing the two values
- * @param <T> the type of the elements to be compared
- * @return a {@code BinaryOperator} which returns the lesser of its operands,
- * according to the supplied {@code Comparator}
- */
- public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
- Objects.requireNonNull(comparator);
- return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
- }
-
- /**
- * Constructs a {@link BinaryOperator} which returns the greater of two elements
- * according to the specified {@code Comparator}
- *
- * @param comparator A {@code Comparator} for comparing the two values
- * @param <T> the type of the elements to be compared
- * @return a {@code BinaryOperator} which returns the greater of its operands,
- * according to the supplied {@code Comparator}
- */
- public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
- Objects.requireNonNull(comparator);
- return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
+ @Override
+ public Comparator<T> reversed() {
+ return new NullComparator(!nullFirst, real == null ? null : real.reversed());
+ }
}
}