src/share/classes/java/util/Comparators.java

Print this page
rev 7485 : 8009736: Comparator API cleanup
Reviewed-by:
Contributed-by: henry.jen@oracle.com

*** 1,7 **** /* ! * Copyright (c) 2012, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 30,281 **** import java.util.function.ToDoubleFunction; import java.util.function.ToIntFunction; 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 */ ! public class Comparators { private Comparators() { throw new AssertionError("no instances"); } /** * Compares {@link Comparable} objects in natural order. * * @see Comparable */ ! private 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()); ! } ! ! /** ! * 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 ! */ ! 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} 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)); } - - /** - * 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)); } ! /** ! * 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); ! }; } ! /** ! * 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; } } --- 30,93 ---- import java.util.function.ToDoubleFunction; import java.util.function.ToIntFunction; import java.util.function.ToLongFunction; /** ! * Package private supporting class for {@link Comparator}. */ ! class Comparators { private Comparators() { throw new AssertionError("no instances"); } /** * Compares {@link Comparable} objects in natural order. * * @see Comparable */ ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; @Override public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c1.compareTo(c2); } } /** ! * Null-friendly comparators */ ! 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; ! ! @SuppressWarnings("unchecked") ! NullComparator(boolean nullFirst, Comparator<? super T> real) { ! this.nullFirst = nullFirst; ! this.real = (Comparator<T>) real; } ! @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); } } ! @Override ! public Comparator<T> thenComparing(Comparator<? super T> other) { ! Objects.requireNonNull(other); ! return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other)); } ! @Override ! public Comparator<T> reversed() { ! return new NullComparator(!nullFirst, real == null ? null : real.reversed()); } } }