jdk/src/java.base/share/classes/java/util/Objects.java
changeset 37345 9cb6e1141bdb
parent 34360 1b8b4b0b1608
child 38356 1e4ecca97792
equal deleted inserted replaced
37344:52d3d8517efc 37345:9cb6e1141bdb
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package java.util;
    26 package java.util;
    27 
    27 
       
    28 import jdk.internal.HotSpotIntrinsicCandidate;
       
    29 
    28 import java.util.function.BiFunction;
    30 import java.util.function.BiFunction;
       
    31 import java.util.function.Function;
    29 import java.util.function.Supplier;
    32 import java.util.function.Supplier;
    30 import jdk.internal.HotSpotIntrinsicCandidate;
       
    31 
    33 
    32 /**
    34 /**
    33  * This class consists of {@code static} utility methods for operating
    35  * This class consists of {@code static} utility methods for operating
    34  * on objects, or checking certain conditions before operation.  These utilities
    36  * on objects, or checking certain conditions before operation.  These utilities
    35  * include {@code null}-safe or {@code null}-tolerant methods for computing the
    37  * include {@code null}-safe or {@code null}-tolerant methods for computing the
    36  * hash code of an object, returning a string for an object, comparing two
    38  * hash code of an object, returning a string for an object, comparing two
    37  * objects, and checking if indexes or sub-range values are out of bounds.
    39  * objects, and checking if indexes or sub-range values are out-of-bounds.
    38  *
    40  *
    39  * @apiNote
    41  * @apiNote
    40  * Static methods such as {@link Objects#checkIndex},
    42  * Static methods such as {@link Objects#checkIndex},
    41  * {@link Objects#checkFromToIndex}, and {@link Objects#checkFromIndexSize} are
    43  * {@link Objects#checkFromToIndex}, and {@link Objects#checkFromIndexSize} are
    42  * provided for the convenience of checking if values corresponding to indexes
    44  * provided for the convenience of checking if values corresponding to indexes
    43  * and sub-ranges are out of bounds.
    45  * and sub-ranges are out-of-bounds.
    44  * Variations of these static methods support customization of the runtime
    46  * Variations of these static methods support customization of the runtime
    45  * exception, and corresponding exception detail message, that is thrown when
    47  * exception, and corresponding exception detail message, that is thrown when
    46  * values are out of bounds.  Such methods accept a functional interface
    48  * values are out-of-bounds.  Such methods accept a functional interface
    47  * argument, instances of {@code BiFunction}, that maps out of bound values to a
    49  * argument, instances of {@code BiFunction}, that maps out-of-bound values to a
    48  * runtime exception.  Care should be taken when using such methods in
    50  * runtime exception.  Care should be taken when using such methods in
    49  * combination with an argument that is a lambda expression, method reference or
    51  * combination with an argument that is a lambda expression, method reference or
    50  * class that capture values.  In such cases the cost of capture, related to
    52  * class that capture values.  In such cases the cost of capture, related to
    51  * functional interface allocation, may exceed the cost of checking bounds.
    53  * functional interface allocation, may exceed the cost of checking bounds.
    52  *
    54  *
   345             throw new NullPointerException(messageSupplier.get());
   347             throw new NullPointerException(messageSupplier.get());
   346         return obj;
   348         return obj;
   347     }
   349     }
   348 
   350 
   349     /**
   351     /**
   350      * Maps out of bounds values to a runtime exception.
   352      * Maps out-of-bounds values to a runtime exception.
   351      *
   353      *
   352      * @param a the first out of bound value
   354      * @param checkKind the kind of bounds check, whose name may correspond
   353      * @param b the second out of bound value
   355      *        to the name of one of the range check methods, checkIndex,
   354      * @param oobe the exception mapping function that when applied with out of
   356      *        checkFromToIndex, checkFromIndexSize
   355      *        bounds arguments returns a runtime exception.  If {@code null}
   357      * @param args the out-of-bounds arguments that failed the range check.
   356      *        then, it is as if an exception mapping function was supplied that
   358      *        If the checkKind corresponds a the name of a range check method
   357      *        returns {@link IndexOutOfBoundsException} for any given arguments.
   359      *        then the bounds arguments are those that can be passed in order
       
   360      *        to the method.
       
   361      * @param oobef the exception formatter that when applied with a checkKind
       
   362      *        and a list out-of-bounds arguments returns a runtime exception.
       
   363      *        If {@code null} then, it is as if an exception formatter was
       
   364      *        supplied that returns {@link IndexOutOfBoundsException} for any
       
   365      *        given arguments.
   358      * @return the runtime exception
   366      * @return the runtime exception
   359      */
   367      */
   360     private static RuntimeException outOfBounds(
   368     private static RuntimeException outOfBounds(
   361             int a, int b, BiFunction<Integer, Integer, ? extends RuntimeException> oobe) {
   369             BiFunction<String, List<Integer>, ? extends RuntimeException> oobef,
   362         RuntimeException e = oobe == null
   370             String checkKind,
   363                              ? null : oobe.apply(a, b);
   371             Integer... args) {
       
   372         List<Integer> largs = List.of(args);
       
   373         RuntimeException e = oobef == null
       
   374                              ? null : oobef.apply(checkKind, largs);
   364         return e == null
   375         return e == null
   365                ? new IndexOutOfBoundsException(a, b) : e;
   376                ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e;
       
   377     }
       
   378 
       
   379     // Specific out-of-bounds exception producing methods that avoid
       
   380     // the varargs-based code in the critical methods there by reducing their
       
   381     // the byte code size, and therefore less likely to peturb inlining
       
   382 
       
   383     private static RuntimeException outOfBoundsCheckIndex(
       
   384             BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
       
   385             int index, int length) {
       
   386         return outOfBounds(oobe, "checkIndex", index, length);
       
   387     }
       
   388 
       
   389     private static RuntimeException outOfBoundsCheckFromToIndex(
       
   390             BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
       
   391             int fromIndex, int toIndex, int length) {
       
   392         return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
       
   393     }
       
   394 
       
   395     private static RuntimeException outOfBoundsCheckFromIndexSize(
       
   396             BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
       
   397             int fromIndex, int size, int length) {
       
   398         return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
       
   399     }
       
   400 
       
   401     /**
       
   402      * Returns an out-of-bounds exception formatter from an given exception
       
   403      * factory.  The exception formatter is a function that formats an
       
   404      * out-of-bounds message from its arguments and applies that message to the
       
   405      * given exception factory to produce and relay an exception.
       
   406      *
       
   407      * <p>The exception formatter accepts two arguments: a {@code String}
       
   408      * describing the out-of-bounds range check that failed, referred to as the
       
   409      * <em>check kind</em>; and a {@code List<Integer>} containing the
       
   410      * out-of-bound integer values that failed the check.  The list of
       
   411      * out-of-bound values is not modified.
       
   412      *
       
   413      * <p>Three check kinds are supported {@code checkIndex},
       
   414      * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding
       
   415      * respectively to the specified application of an exception formatter as an
       
   416      * argument to the out-of-bounds range check methods
       
   417      * {@link #checkIndex(int, int, BiFunction) checkIndex},
       
   418      * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and
       
   419      * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}.
       
   420      * Thus a supported check kind corresponds to a method name and the
       
   421      * out-of-bound integer values correspond to method argument values, in
       
   422      * order, preceding the exception formatter argument (similar in many
       
   423      * respects to the form of arguments required for a reflective invocation of
       
   424      * such a range check method).
       
   425      *
       
   426      * <p>Formatter arguments conforming to such supported check kinds will
       
   427      * produce specific exception messages describing failed out-of-bounds
       
   428      * checks.  Otherwise, more generic exception messages will be produced in
       
   429      * any of the following cases: the check kind is supported but fewer
       
   430      * or more out-of-bounds values are supplied, the check kind is not
       
   431      * supported, the check kind is {@code null}, or the list of out-of-bound
       
   432      * values is {@code null}.
       
   433      *
       
   434      * @apiNote
       
   435      * This method produces an out-of-bounds exception formatter that can be
       
   436      * passed as an argument to any of the supported out-of-bounds range check
       
   437      * methods declared by {@code Objects}.  For example, a formatter producing
       
   438      * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a
       
   439      * {@code static final} field as follows:
       
   440      * <pre>{@code
       
   441      * static final
       
   442      * BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF =
       
   443      *     outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new);
       
   444      * }</pre>
       
   445      * The formatter instance {@code AIOOBEF} may be passed as an argument to an
       
   446      * out-of-bounds range check method, such as checking if an {@code index}
       
   447      * is within the bounds of a {@code limit}:
       
   448      * <pre>{@code
       
   449      * checkIndex(index, limit, AIOOBEF);
       
   450      * }</pre>
       
   451      * If the bounds check fails then the range check method will throw an
       
   452      * {@code ArrayIndexOutOfBoundsException} with an appropriate exception
       
   453      * message that is a produced from {@code AIOOBEF} as follows:
       
   454      * <pre>{@code
       
   455      * AIOOBEF.apply("checkIndex", List.of(index, limit));
       
   456      * }</pre>
       
   457      *
       
   458      * @param f the exception factory, that produces an exception from a message
       
   459      *        where the message is produced and formatted by the returned
       
   460      *        exception formatter.  If this factory is stateless and side-effect
       
   461      *        free then so is the returned formatter.
       
   462      *        Exceptions thrown by the factory are relayed to the caller
       
   463      *        of the returned formatter.
       
   464      * @param <X> the type of runtime exception to be returned by the given
       
   465      *        exception factory and relayed by the exception formatter
       
   466      * @return the out-of-bounds exception formatter
       
   467      */
       
   468     public static <X extends RuntimeException>
       
   469     BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) {
       
   470         // Use anonymous class to avoid bootstrap issues if this method is
       
   471         // used early in startup
       
   472         return new BiFunction<String, List<Integer>, X>() {
       
   473             @Override
       
   474             public X apply(String checkKind, List<Integer> args) {
       
   475                 return f.apply(outOfBoundsMessage(checkKind, args));
       
   476             }
       
   477         };
       
   478     }
       
   479 
       
   480     private static String outOfBoundsMessage(String checkKind, List<Integer> args) {
       
   481         if (checkKind == null && args == null) {
       
   482             return String.format("Range check failed");
       
   483         } else if (checkKind == null) {
       
   484             return String.format("Range check failed: %s", args);
       
   485         } else if (args == null) {
       
   486             return String.format("Range check failed: %s", checkKind);
       
   487         }
       
   488 
       
   489         int argSize = 0;
       
   490         switch (checkKind) {
       
   491             case "checkIndex":
       
   492                 argSize = 2;
       
   493                 break;
       
   494             case "checkFromToIndex":
       
   495             case "checkFromIndexSize":
       
   496                 argSize = 3;
       
   497                 break;
       
   498             default:
       
   499         }
       
   500 
       
   501         // Switch to default if fewer or more arguments than required are supplied
       
   502         switch ((args.size() != argSize) ? "" : checkKind) {
       
   503             case "checkIndex":
       
   504                 return String.format("Index %d out-of-bounds for length %d",
       
   505                                      args.get(0), args.get(1));
       
   506             case "checkFromToIndex":
       
   507                 return String.format("Range [%d, %d) out-of-bounds for length %d",
       
   508                                      args.get(0), args.get(1), args.get(2));
       
   509             case "checkFromIndexSize":
       
   510                 return String.format("Range [%d, %<d + %d) out-of-bounds for length %d",
       
   511                                      args.get(0), args.get(1), args.get(2));
       
   512             default:
       
   513                 return String.format("Range check failed: %s %s", checkKind, args);
       
   514         }
   366     }
   515     }
   367 
   516 
   368     /**
   517     /**
   369      * Checks if the {@code index} is within the bounds of the range from
   518      * Checks if the {@code index} is within the bounds of the range from
   370      * {@code 0} (inclusive) to {@code length} (exclusive).
   519      * {@code 0} (inclusive) to {@code length} (exclusive).
   371      *
   520      *
   372      * <p>The {@code index} is defined to be out of bounds if any of the
   521      * <p>The {@code index} is defined to be out-of-bounds if any of the
   373      * following inequalities is true:
   522      * following inequalities is true:
   374      * <ul>
   523      * <ul>
   375      *  <li>{@code index < 0}</li>
   524      *  <li>{@code index < 0}</li>
   376      *  <li>{@code index >= length}</li>
   525      *  <li>{@code index >= length}</li>
   377      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   526      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   378      * </ul>
   527      * </ul>
   379      *
   528      *
       
   529      * <p>This method behaves as if {@link #checkIndex(int, int, BiFunction)}
       
   530      * was called with same out-of-bounds arguments and an exception formatter
       
   531      * argument produced from an invocation of
       
   532      * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
       
   533      * be more efficient).
       
   534      *
   380      * @param index the index
   535      * @param index the index
   381      * @param length the upper-bound (exclusive) of the range
   536      * @param length the upper-bound (exclusive) of the range
   382      * @return {@code index} if it is within bounds of the range
   537      * @return {@code index} if it is within bounds of the range
   383      * @throws IndexOutOfBoundsException if the {@code index} is out of bounds
   538      * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
   384      * @since 9
   539      * @since 9
   385      */
   540      */
   386     public static
   541     public static
   387     int checkIndex(int index, int length) throws IndexOutOfBoundsException {
   542     int checkIndex(int index, int length) {
   388         return checkIndex(index, length, null);
   543         return checkIndex(index, length, null);
   389     }
   544     }
   390 
   545 
   391     /**
   546     /**
   392      * Checks if the {@code index} is within the bounds of the range from
   547      * Checks if the {@code index} is within the bounds of the range from
   393      * {@code 0} (inclusive) to {@code length} (exclusive).
   548      * {@code 0} (inclusive) to {@code length} (exclusive).
   394      *
   549      *
   395      * <p>The {@code index} is defined to be out of bounds if any of the
   550      * <p>The {@code index} is defined to be out-of-bounds if any of the
   396      * following inequalities is true:
   551      * following inequalities is true:
   397      * <ul>
   552      * <ul>
   398      *  <li>{@code index < 0}</li>
   553      *  <li>{@code index < 0}</li>
   399      *  <li>{@code index >= length}</li>
   554      *  <li>{@code index >= length}</li>
   400      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   555      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   401      * </ul>
   556      * </ul>
   402      *
   557      *
   403      * <p>If the {@code index} is out of bounds, then a runtime exception is
   558      * <p>If the {@code index} is out-of-bounds, then a runtime exception is
   404      * thrown that is the result of applying the arguments {@code index} and
   559      * thrown that is the result of applying the following arguments to the
   405      * {@code length} to the given exception mapping function.
   560      * exception formatter: the name of this method, {@code checkIndex};
   406      *
   561      * and an unmodifiable list integers whose values are, in order, the
   407      * @param <T> the type of runtime exception to throw if the arguments are
   562      * out-of-bounds arguments {@code index} and {@code length}.
   408      *        out of bounds
   563      *
       
   564      * @param <X> the type of runtime exception to throw if the arguments are
       
   565      *        out-of-bounds
   409      * @param index the index
   566      * @param index the index
   410      * @param length the upper-bound (exclusive) of the range
   567      * @param length the upper-bound (exclusive) of the range
   411      * @param oobe the exception mapping function that when applied with out
   568      * @param oobef the exception formatter that when applied with this
   412      *        of bounds arguments returns a runtime exception.  If {@code null}
   569      *        method name and out-of-bounds arguments returns a runtime
   413      *        or returns {@code null} then, it is as if an exception mapping
   570      *        exception.  If {@code null} or returns {@code null} then, it is as
   414      *        function was supplied that returns
   571      *        if an exception formatter produced from an invocation of
   415      *        {@link IndexOutOfBoundsException} for any given arguments.
   572      *        {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
   416      *        Exceptions thrown by the function are relayed to the caller.
   573      *        instead (though it may be more efficient).
       
   574      *        Exceptions thrown by the formatter are relayed to the caller.
   417      * @return {@code index} if it is within bounds of the range
   575      * @return {@code index} if it is within bounds of the range
   418      * @throws T if the {@code index} is out of bounds, then a runtime exception
   576      * @throws X if the {@code index} is out-of-bounds and the exception
   419      *         is thrown that is the result of applying the out of bounds
   577      *         formatter is non-{@code null}
   420      *         arguments to the exception mapping function.
   578      * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
   421      * @throws IndexOutOfBoundsException if the {@code index} is out of bounds
   579      *         and the exception formatter is {@code null}
   422      *         and the exception mapping function is {@code null}
       
   423      * @since 9
   580      * @since 9
   424      *
   581      *
   425      * @implNote
   582      * @implNote
   426      * This method is made intrinsic in optimizing compilers to guide
   583      * This method is made intrinsic in optimizing compilers to guide them to
   427      * them to perform unsigned comparisons of the index and length
   584      * perform unsigned comparisons of the index and length when it is known the
   428      * when it is known the length is a non-negative value (such as
   585      * length is a non-negative value (such as that of an array length or from
   429      * that of an array length or from the upper bound of a loop)
   586      * the upper bound of a loop)
   430     */
   587     */
   431     @HotSpotIntrinsicCandidate
   588     @HotSpotIntrinsicCandidate
   432     public static <T extends RuntimeException>
   589     public static <X extends RuntimeException>
   433     int checkIndex(int index, int length,
   590     int checkIndex(int index, int length,
   434                    BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
   591                    BiFunction<String, List<Integer>, X> oobef) {
   435         if (index < 0 || index >= length)
   592         if (index < 0 || index >= length)
   436             throw outOfBounds(index, length, oobe);
   593             throw outOfBoundsCheckIndex(oobef, index, length);
   437         return index;
   594         return index;
   438     }
   595     }
   439 
   596 
   440     /**
   597     /**
   441      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   598      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   442      * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
   599      * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
   443      * (inclusive) to {@code length} (exclusive).
   600      * (inclusive) to {@code length} (exclusive).
   444      *
   601      *
   445      * <p>The sub-range is defined to be out of bounds if any of the following
   602      * <p>The sub-range is defined to be out-of-bounds if any of the following
   446      * inequalities is true:
   603      * inequalities is true:
   447      * <ul>
   604      * <ul>
   448      *  <li>{@code fromIndex < 0}</li>
   605      *  <li>{@code fromIndex < 0}</li>
   449      *  <li>{@code fromIndex > toIndex}</li>
   606      *  <li>{@code fromIndex > toIndex}</li>
   450      *  <li>{@code toIndex > length}</li>
   607      *  <li>{@code toIndex > length}</li>
   451      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   608      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   452      * </ul>
   609      * </ul>
   453      *
   610      *
       
   611      * <p>This method behaves as if {@link #checkFromToIndex(int, int, int, BiFunction)}
       
   612      * was called with same out-of-bounds arguments and an exception formatter
       
   613      * argument produced from an invocation of
       
   614      * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
       
   615      * be more efficient).
       
   616      *
   454      * @param fromIndex the lower-bound (inclusive) of the sub-range
   617      * @param fromIndex the lower-bound (inclusive) of the sub-range
   455      * @param toIndex the upper-bound (exclusive) of the sub-range
   618      * @param toIndex the upper-bound (exclusive) of the sub-range
   456      * @param length the upper-bound (exclusive) the range
   619      * @param length the upper-bound (exclusive) the range
   457      * @return {@code fromIndex} if the sub-range within bounds of the range
   620      * @return {@code fromIndex} if the sub-range within bounds of the range
   458      * @throws IndexOutOfBoundsException if the sub-range is out of bounds
   621      * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds
   459      * @since 9
   622      * @since 9
   460      */
   623      */
   461     public static
   624     public static
   462     int checkFromToIndex(int fromIndex, int toIndex, int length) throws IndexOutOfBoundsException {
   625     int checkFromToIndex(int fromIndex, int toIndex, int length) {
   463         return checkFromToIndex(fromIndex, toIndex, length, null);
   626         return checkFromToIndex(fromIndex, toIndex, length, null);
   464     }
   627     }
   465 
   628 
   466     /**
   629     /**
   467      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   630      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   468      * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
   631      * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
   469      * (inclusive) to {@code length} (exclusive).
   632      * (inclusive) to {@code length} (exclusive).
   470      *
   633      *
   471      * <p>The sub-range is defined to be out of bounds if any of the following
   634      * <p>The sub-range is defined to be out-of-bounds if any of the following
   472      * inequalities is true:
   635      * inequalities is true:
   473      * <ul>
   636      * <ul>
   474      *  <li>{@code fromIndex < 0}</li>
   637      *  <li>{@code fromIndex < 0}</li>
   475      *  <li>{@code fromIndex > toIndex}</li>
   638      *  <li>{@code fromIndex > toIndex}</li>
   476      *  <li>{@code toIndex > length}</li>
   639      *  <li>{@code toIndex > length}</li>
   477      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   640      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   478      * </ul>
   641      * </ul>
   479      *
   642      *
   480      * <p>If the sub-range is out of bounds, then a runtime exception is thrown
   643      * <p>If the sub-range  is out-of-bounds, then a runtime exception is
   481      * that is the result of applying the arguments {@code fromIndex} and
   644      * thrown that is the result of applying the following arguments to the
   482      * {@code toIndex} to the given exception mapping function.
   645      * exception formatter: the name of this method, {@code checkFromToIndex};
   483      *
   646      * and an unmodifiable list integers whose values are, in order, the
   484      * @param <T> the type of runtime exception to throw if the arguments are
   647      * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
   485      *        out of bounds
   648      *
       
   649      * @param <X> the type of runtime exception to throw if the arguments are
       
   650      *        out-of-bounds
   486      * @param fromIndex the lower-bound (inclusive) of the sub-range
   651      * @param fromIndex the lower-bound (inclusive) of the sub-range
   487      * @param toIndex the upper-bound (exclusive) of the sub-range
   652      * @param toIndex the upper-bound (exclusive) of the sub-range
   488      * @param length the upper-bound (exclusive) the range
   653      * @param length the upper-bound (exclusive) the range
   489      * @param oobe the exception mapping function that when applied with out
   654      * @param oobef the exception formatter that when applied with this
   490      *        of bounds arguments returns a runtime exception.  If {@code null}
   655      *        method name and out-of-bounds arguments returns a runtime
   491      *        or returns {@code null} then, it is as if an exception mapping
   656      *        exception.  If {@code null} or returns {@code null} then, it is as
   492      *        function was supplied that returns
   657      *        if an exception formatter produced from an invocation of
   493      *        {@link IndexOutOfBoundsException} for any given arguments.
   658      *        {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
   494      *        Exceptions thrown by the function are relayed to the caller.
   659      *        instead (though it may be more efficient).
       
   660      *        Exceptions thrown by the formatter are relayed to the caller.
   495      * @return {@code fromIndex} if the sub-range within bounds of the range
   661      * @return {@code fromIndex} if the sub-range within bounds of the range
   496      * @throws T if the sub-range is out of bounds, then a runtime exception is
   662      * @throws X if the sub-range is out-of-bounds and the exception factory
   497      *         thrown that is the result of applying the out of bounds arguments
   663      *         function is non-{@code null}
   498      *         to the exception mapping function.
   664      * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
   499      * @throws IndexOutOfBoundsException if the sub-range is out of bounds and
   665      *         the exception factory function is {@code null}
   500      *         the exception mapping function is {@code null}
       
   501      * @since 9
   666      * @since 9
   502      */
   667      */
   503     public static <T extends RuntimeException>
   668     public static <X extends RuntimeException>
   504     int checkFromToIndex(int fromIndex, int toIndex, int length,
   669     int checkFromToIndex(int fromIndex, int toIndex, int length,
   505                          BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
   670                          BiFunction<String, List<Integer>, X> oobef) {
   506         if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
   671         if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
   507             throw outOfBounds(fromIndex, toIndex, oobe);
   672             throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
   508         return fromIndex;
   673         return fromIndex;
   509     }
   674     }
   510 
   675 
   511     /**
   676     /**
   512      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   677      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   513      * {@code fromIndex + size} (exclusive) is within the bounds of range from
   678      * {@code fromIndex + size} (exclusive) is within the bounds of range from
   514      * {@code 0} (inclusive) to {@code length} (exclusive).
   679      * {@code 0} (inclusive) to {@code length} (exclusive).
   515      *
   680      *
   516      * <p>The sub-range is defined to be out of bounds if any of the following
   681      * <p>The sub-range is defined to be out-of-bounds if any of the following
   517      * inequalities is true:
   682      * inequalities is true:
   518      * <ul>
   683      * <ul>
   519      *  <li>{@code fromIndex < 0}</li>
   684      *  <li>{@code fromIndex < 0}</li>
   520      *  <li>{@code size < 0}</li>
   685      *  <li>{@code size < 0}</li>
   521      *  <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
   686      *  <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
   522      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   687      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   523      * </ul>
   688      * </ul>
   524      *
   689      *
       
   690      * <p>This method behaves as if {@link #checkFromIndexSize(int, int, int, BiFunction)}
       
   691      * was called with same out-of-bounds arguments and an exception formatter
       
   692      * argument produced from an invocation of
       
   693      * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
       
   694      * be more efficient).
       
   695      *
   525      * @param fromIndex the lower-bound (inclusive) of the sub-interval
   696      * @param fromIndex the lower-bound (inclusive) of the sub-interval
   526      * @param size the size of the sub-range
   697      * @param size the size of the sub-range
   527      * @param length the upper-bound (exclusive) of the range
   698      * @param length the upper-bound (exclusive) of the range
   528      * @return {@code fromIndex} if the sub-range within bounds of the range
   699      * @return {@code fromIndex} if the sub-range within bounds of the range
   529      * @throws IndexOutOfBoundsException if the sub-range is out of bounds
   700      * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds
   530      * @since 9
   701      * @since 9
   531      */
   702      */
   532     public static
   703     public static
   533     int checkFromIndexSize(int fromIndex, int size, int length) throws IndexOutOfBoundsException {
   704     int checkFromIndexSize(int fromIndex, int size, int length) {
   534         return checkFromIndexSize(fromIndex, size, length, null);
   705         return checkFromIndexSize(fromIndex, size, length, null);
   535     }
   706     }
   536 
   707 
   537     /**
   708     /**
   538      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   709      * Checks if the sub-range from {@code fromIndex} (inclusive) to
   539      * {@code fromIndex + size} (exclusive) is within the bounds of range from
   710      * {@code fromIndex + size} (exclusive) is within the bounds of range from
   540      * {@code 0} (inclusive) to {@code length} (exclusive).
   711      * {@code 0} (inclusive) to {@code length} (exclusive).
   541      *
   712      *
   542      * <p>The sub-range is defined to be out of bounds if any of the following
   713      * <p>The sub-range is defined to be out-of-bounds if any of the following
   543      * inequalities is true:
   714      * inequalities is true:
   544      * <ul>
   715      * <ul>
   545      *  <li>{@code fromIndex < 0}</li>
   716      *  <li>{@code fromIndex < 0}</li>
   546      *  <li>{@code size < 0}</li>
   717      *  <li>{@code size < 0}</li>
   547      *  <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
   718      *  <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
   548      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   719      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
   549      * </ul>
   720      * </ul>
   550      *
   721      *
   551      * <p>If the sub-range is out of bounds then, a runtime exception is thrown
   722      * <p>If the sub-range  is out-of-bounds, then a runtime exception is
   552      * that is the result of applying the arguments {@code fromIndex} and
   723      * thrown that is the result of applying the following arguments to the
   553      * {@code size} to the given exception mapping function.
   724      * exception formatter: the name of this method, {@code checkFromIndexSize};
   554      *
   725      * and an unmodifiable list integers whose values are, in order, the
   555      * @param <T> the type of runtime exception to throw if the arguments are
   726      * out-of-bounds arguments {@code fromIndex}, {@code size}, and
   556      *        out of bounds
   727      * {@code length}.
       
   728      *
       
   729      * @param <X> the type of runtime exception to throw if the arguments are
       
   730      *        out-of-bounds
   557      * @param fromIndex the lower-bound (inclusive) of the sub-interval
   731      * @param fromIndex the lower-bound (inclusive) of the sub-interval
   558      * @param size the size of the sub-range
   732      * @param size the size of the sub-range
   559      * @param length the upper-bound (exclusive) of the range
   733      * @param length the upper-bound (exclusive) of the range
   560      * @param oobe the exception mapping function that when applied with out
   734      * @param oobef the exception formatter that when applied with this
   561      *        of bounds arguments returns a runtime exception.  If {@code null}
   735      *        method name and out-of-bounds arguments returns a runtime
   562      *        or returns {@code null} then, it is as if an exception mapping
   736      *        exception.  If {@code null} or returns {@code null} then, it is as
   563      *        function was supplied that returns
   737      *        if an exception formatter produced from an invocation of
   564      *        {@link IndexOutOfBoundsException} for any given arguments.
   738      *        {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
   565      *        Exceptions thrown by the function are relayed to the caller.
   739      *        instead (though it may be more efficient).
       
   740      *        Exceptions thrown by the formatter are relayed to the caller.
   566      * @return {@code fromIndex} if the sub-range within bounds of the range
   741      * @return {@code fromIndex} if the sub-range within bounds of the range
   567      * @throws T if the sub-range is out of bounds, then a runtime exception is
   742      * @throws X if the sub-range is out-of-bounds and the exception factory
   568      *         thrown that is the result of applying the out of bounds arguments
   743      *         function is non-{@code null}
   569      *         to the exception mapping function.
   744      * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
   570      * @throws IndexOutOfBoundsException if the sub-range is out of bounds and
   745      *         the exception factory function is {@code null}
   571      *         the exception mapping function is {@code null}
       
   572      * @since 9
   746      * @since 9
   573      */
   747      */
   574     public static <T extends RuntimeException>
   748     public static <X extends RuntimeException>
   575     int checkFromIndexSize(int fromIndex, int size, int length,
   749     int checkFromIndexSize(int fromIndex, int size, int length,
   576                            BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
   750                            BiFunction<String, List<Integer>, X> oobef) {
   577         if ((length | fromIndex | size) < 0 || size > length - fromIndex)
   751         if ((length | fromIndex | size) < 0 || size > length - fromIndex)
   578             throw outOfBounds(fromIndex, size, oobe);
   752             throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
   579         return fromIndex;
   753         return fromIndex;
   580     }
   754     }
   581 }
   755 }