< prev index next >

src/java.base/share/classes/java/util/Comparator.java

Print this page
rev 17656 : [mq]: 8134512-provide-Alpha-Numeric-logical-Comparator


  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import java.io.Serializable;
  29 import java.util.function.Function;
  30 import java.util.function.ToIntFunction;
  31 import java.util.function.ToLongFunction;
  32 import java.util.function.ToDoubleFunction;
  33 import java.util.Comparators;
  34 
  35 /**
  36  * A comparison function, which imposes a <i>total ordering</i> on some
  37  * collection of objects.  Comparators can be passed to a sort method (such
  38  * as {@link Collections#sort(List,Comparator) Collections.sort} or {@link
  39  * Arrays#sort(Object[],Comparator) Arrays.sort}) to allow precise control
  40  * over the sort order.  Comparators can also be used to control the order of
  41  * certain data structures (such as {@link SortedSet sorted sets} or {@link
  42  * SortedMap sorted maps}), or to provide an ordering for collections of
  43  * objects that don't have a {@link Comparable natural ordering}.<p>
  44  *
  45  * The ordering imposed by a comparator {@code c} on a set of elements
  46  * {@code S} is said to be <i>consistent with equals</i> if and only if
  47  * {@code c.compare(e1, e2)==0} has the same boolean value as
  48  * {@code e1.equals(e2)} for every {@code e1} and {@code e2} in
  49  * {@code S}.<p>
  50  *
  51  * Caution should be exercised when using a comparator capable of imposing an
  52  * ordering inconsistent with equals to order a sorted set (or sorted map).
  53  * Suppose a sorted set (or sorted map) with an explicit comparator {@code c}


 509         Objects.requireNonNull(keyExtractor);
 510         return (Comparator<T> & Serializable)
 511             (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
 512     }
 513 
 514     /**
 515      * Accepts a function that extracts a {@code double} sort key from a type
 516      * {@code T}, and returns a {@code Comparator<T>} that compares by that
 517      * sort key.
 518      *
 519      * <p>The returned comparator is serializable if the specified function
 520      * is also serializable.
 521      *
 522      * @param  <T> the type of element to be compared
 523      * @param  keyExtractor the function used to extract the double sort key
 524      * @return a comparator that compares by an extracted key
 525      * @see #comparing(Function)
 526      * @throws NullPointerException if the argument is null
 527      * @since 1.8
 528      */
 529     public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
 530         Objects.requireNonNull(keyExtractor);
 531         return (Comparator<T> & Serializable)
 532             (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));

























































































































































 533     }
 534 }


  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util;
  27 
  28 import java.io.Serializable;
  29 import java.util.function.Function;
  30 import java.util.function.ToIntFunction;
  31 import java.util.function.ToLongFunction;
  32 import java.util.function.ToDoubleFunction;

  33 
  34 /**
  35  * A comparison function, which imposes a <i>total ordering</i> on some
  36  * collection of objects.  Comparators can be passed to a sort method (such
  37  * as {@link Collections#sort(List,Comparator) Collections.sort} or {@link
  38  * Arrays#sort(Object[],Comparator) Arrays.sort}) to allow precise control
  39  * over the sort order.  Comparators can also be used to control the order of
  40  * certain data structures (such as {@link SortedSet sorted sets} or {@link
  41  * SortedMap sorted maps}), or to provide an ordering for collections of
  42  * objects that don't have a {@link Comparable natural ordering}.<p>
  43  *
  44  * The ordering imposed by a comparator {@code c} on a set of elements
  45  * {@code S} is said to be <i>consistent with equals</i> if and only if
  46  * {@code c.compare(e1, e2)==0} has the same boolean value as
  47  * {@code e1.equals(e2)} for every {@code e1} and {@code e2} in
  48  * {@code S}.<p>
  49  *
  50  * Caution should be exercised when using a comparator capable of imposing an
  51  * ordering inconsistent with equals to order a sorted set (or sorted map).
  52  * Suppose a sorted set (or sorted map) with an explicit comparator {@code c}


 508         Objects.requireNonNull(keyExtractor);
 509         return (Comparator<T> & Serializable)
 510             (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
 511     }
 512 
 513     /**
 514      * Accepts a function that extracts a {@code double} sort key from a type
 515      * {@code T}, and returns a {@code Comparator<T>} that compares by that
 516      * sort key.
 517      *
 518      * <p>The returned comparator is serializable if the specified function
 519      * is also serializable.
 520      *
 521      * @param  <T> the type of element to be compared
 522      * @param  keyExtractor the function used to extract the double sort key
 523      * @return a comparator that compares by an extracted key
 524      * @see #comparing(Function)
 525      * @throws NullPointerException if the argument is null
 526      * @since 1.8
 527      */
 528     public static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
 529         Objects.requireNonNull(keyExtractor);
 530         return (Comparator<T> & Serializable)
 531             (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
 532     }
 533 
 534     /**
 535      * The returned comparator compares two character sequences as though each
 536      * of them would be first transformed into a tuple of the form:
 537      * <pre>{@code (A0, N0, A1, N1, ..., An-1, Nn-1, An, Nn)}</pre>
 538      * where:
 539      * <p>{@code A0} and {@code An} are (possibly empty) sub-sequences
 540      * consisting of non-decimal-digit characters,
 541      * <p>{@code A1 ... An-1} are non-empty sub-sequences consisting of
 542      * non-decimal-digit characters,
 543      * <p>{@code N0 ... Nn-1} are non-empty sub-sequences consisting of
 544      * decimal-digit characters, and
 545      * <p>{@code Nn} is a (possibly empty) sub-sequence consisting of
 546      * decimal-digit characters.
 547      *
 548      * <p>All sub-sequences concatenated together in order as they appear in the
 549      * tuple yield the original character sequence.
 550      *
 551      * After transformation, the tuples are compared by their elements (from
 552      * left to right) so that corresponding {@code Ax} elements are compared
 553      * using the provided comparator {@code alphaComparator} and {@code Nx}
 554      * elements are compared as non negative decimal integers.
 555      *
 556      * The first pair of compared elements that is different with respect to the
 557      * used comparator (either {@code alphaComparator}, or special decimal
 558      * comparator) if any, provides the result produced by this comparator.
 559      * The arguments are treated equal, if and only if all the subsequences,
 560      * both decimal and non-decimal, compare equal.
 561      *
 562      * <p>For example, the following array was sorted using such comparator:
 563      * <pre>{@code
 564      * { "1ab", "5ab", "10ab",
 565      *   "a1b", "a5b", "a10b",
 566      *   "ab1", "ab5", "ab10" };}</pre>
 567      *
 568      * <p>When comparing numerical parts, an empty character sequence is
 569      * considered less than any non-empty sequence of decimal digits.
 570      *
 571      * <p>If the numeric values of two compared character sub-sequences are
 572      * equal, but their string representations have different number of leading
 573      * zeroes, the comparator treats the number with less leading zeros as
 574      * smaller.
 575      * For example, {@code "abc 1" < "abc 01" < "abc 001"}.
 576      *
 577      * @apiNote  For example, to sort a collection of {@code String} based on
 578      * case-insensitive ordering, and treating numbers with more leading
 579      * zeroes as greater, one could use
 580      *
 581      * <pre>{@code
 582      *     Comparator<String> cmp = Comparator.comparingAlphaDecimal(
 583      *             Comparator.comparing(CharSequence::toString,
 584      *                                  String::compareToIgnoreCase));
 585      * }</pre>
 586      *
 587      * @implSpec  To test if the given code point represents a decimal digit,
 588      * the comparator checks if {@link java.lang.Character#getType(int)}
 589      * returns value {@link java.lang.Character#DECIMAL_DIGIT_NUMBER}.
 590      * The comparator uses {@link java.lang.Character#digit(int, int)} with
 591      * the second argument set to {@code 10} to determine the numeric
 592      * value of a digit represented by the given code point.
 593      *
 594      * @param  alphaComparator the comparator that compares sub-sequences
 595      *                         consisting of non-decimal-digits
 596      * @param  <T> the type of elements to be compared; normally
 597      *                         {@link java.lang.CharSequence}
 598      * @return a comparator that compares character sequences, following the
 599      *                         rules described above
 600      * @throws NullPointerException if the argument is null
 601      *
 602      * @since 10
 603      */
 604     public static <T extends CharSequence> Comparator<T>
 605     comparingAlphaDecimal(Comparator<? super CharSequence> alphaComparator) {
 606         return new Comparators.AlphaDecimalComparator<>(
 607                 Objects.requireNonNull(alphaComparator), false);
 608     }
 609 
 610     /**
 611      * The returned comparator compares two character sequences as though each
 612      * of them would be first transformed into a tuple of the form:
 613      * <pre>{@code (A0, N0, A1, N1, ..., An-1, Nn-1, An, Nn)}</pre>
 614      * where:
 615      * <p>{@code A0} and {@code An} are (possibly empty) sub-sequences
 616      * consisting of non-decimal-digit characters,
 617      * <p>{@code A1 ... An-1} are non-empty sub-sequences consisting of
 618      * non-decimal-digit characters,
 619      * <p>{@code N0 ... Nn-1} are non-empty sub-sequences consisting of
 620      * decimal-digit characters, and
 621      * <p>{@code Nn} is a (possibly empty) sub-sequence consisting of
 622      * decimal-digit characters.
 623      *
 624      * <p>All sub-sequences concatenated together in order as they appear in the
 625      * tuple yield the original character sequence.
 626      *
 627      * After transformation, the tuples are compared by their elements (from
 628      * left to right) so that corresponding {@code Ax} elements are compared
 629      * using the provided comparator {@code alphaComparator} and {@code Nx}
 630      * elements are compared as non negative decimal integers.
 631      *
 632      * The first pair of compared elements that is different with respect to the
 633      * used comparator (either {@code alphaComparator}, or special decimal
 634      * comparator) if any, provides the result produced by this comparator.
 635      * The arguments are treated equal, if and only if all the subsequences,
 636      * both decimal and non-decimal, compare equal.
 637      *
 638      * <p>For example, the following array was sorted using such comparator:
 639      * <pre>{@code
 640      * { "1ab", "5ab", "10ab",
 641      *   "a1b", "a5b", "a10b",
 642      *   "ab1", "ab5", "ab10" };}</pre>
 643      *
 644      * <p>When comparing numerical parts, an empty character sequence is
 645      * considered less than any non-empty sequence of decimal digits.
 646      *
 647      * <p>If the numeric values of two compared character sub-sequences are
 648      * equal, but their string representations have different number of leading
 649      * zeroes, the comparator treats the number with more leading zeros as
 650      * smaller.
 651      * For example, {@code "abc 001" < "abc 01" < "abc 1"}.
 652      *
 653      * @apiNote  For example, to sort a collection of {@code String} based on
 654      * case-insensitive ordering, and treating numbers with less leading
 655      * zeroes as greater, one could use
 656      *
 657      * <pre>{@code
 658      *       Comparator<String> cmp = Comparator.comparingAlphaDecimalLeadingZeroesFirst(
 659      *             Comparator.comparing(CharSequence::toString,
 660      *                                  String::compareToIgnoreCase));
 661      * }</pre>
 662      *
 663      * @implSpec  To test if the given code point represents a decimal digit,
 664      * the comparator checks if {@link java.lang.Character#getType(int)}
 665      * returns value {@link java.lang.Character#DECIMAL_DIGIT_NUMBER}.
 666      * The comparator uses {@link java.lang.Character#digit(int, int)} with
 667      * the second argument set to {@code 10} to determine the numeric
 668      * value of a digit represented by the given code point.
 669      *
 670      * @param  alphaComparator the comparator that compares sub-sequences
 671      *                         consisting of non-decimal-digits
 672      * @param  <T> the type of elements to be compared; normally
 673      *                         {@link java.lang.CharSequence}
 674      * @return a comparator that compares character sequences, following the
 675      *                         rules described above
 676      * @throws NullPointerException if the argument is null
 677      *
 678      * @since 10
 679      */
 680     public static <T extends CharSequence> Comparator<T>
 681     comparingAlphaDecimalLeadingZeroesFirst(
 682             Comparator<? super CharSequence> alphaComparator) {
 683         return new Comparators.AlphaDecimalComparator<>(
 684                 Objects.requireNonNull(alphaComparator), true);
 685     }
 686 }
< prev index next >