Source for java.util.Arrays

   1: /* Arrays.java -- Utility class with methods to operate on arrays
   2:    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
   3:    Free Software Foundation, Inc.
   4: 
   5: This file is part of GNU Classpath.
   6: 
   7: GNU Classpath is free software; you can redistribute it and/or modify
   8: it under the terms of the GNU General Public License as published by
   9: the Free Software Foundation; either version 2, or (at your option)
  10: any later version.
  11: 
  12: GNU Classpath is distributed in the hope that it will be useful, but
  13: WITHOUT ANY WARRANTY; without even the implied warranty of
  14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15: General Public License for more details.
  16: 
  17: You should have received a copy of the GNU General Public License
  18: along with GNU Classpath; see the file COPYING.  If not, write to the
  19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20: 02110-1301 USA.
  21: 
  22: Linking this library statically or dynamically with other modules is
  23: making a combined work based on this library.  Thus, the terms and
  24: conditions of the GNU General Public License cover the whole
  25: combination.
  26: 
  27: As a special exception, the copyright holders of this library give you
  28: permission to link this library with independent modules to produce an
  29: executable, regardless of the license terms of these independent
  30: modules, and to copy and distribute the resulting executable under
  31: terms of your choice, provided that you also meet, for each linked
  32: independent module, the terms and conditions of the license of that
  33: module.  An independent module is a module which is not derived from
  34: or based on this library.  If you modify this library, you may extend
  35: this exception to your version of the library, but you are not
  36: obligated to do so.  If you do not wish to do so, delete this
  37: exception statement from your version. */
  38: 
  39: 
  40: package java.util;
  41: 
  42: import java.io.Serializable;
  43: import java.lang.reflect.Array;
  44: 
  45: /**
  46:  * This class contains various static utility methods performing operations on
  47:  * arrays, and a method to provide a List "view" of an array to facilitate
  48:  * using arrays with Collection-based APIs. All methods throw a
  49:  * {@link NullPointerException} if the parameter array is null.
  50:  * <p>
  51:  *
  52:  * Implementations may use their own algorithms, but must obey the general
  53:  * properties; for example, the sort must be stable and n*log(n) complexity.
  54:  * Sun's implementation of sort, and therefore ours, is a tuned quicksort,
  55:  * adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering a Sort
  56:  * Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265
  57:  * (November 1993). This algorithm offers n*log(n) performance on many data
  58:  * sets that cause other quicksorts to degrade to quadratic performance.
  59:  *
  60:  * @author Original author unknown
  61:  * @author Bryce McKinlay
  62:  * @author Eric Blake (ebb9@email.byu.edu)
  63:  * @see Comparable
  64:  * @see Comparator
  65:  * @since 1.2
  66:  * @status updated to 1.4
  67:  */
  68: public class Arrays
  69: {
  70:   /**
  71:    * This class is non-instantiable.
  72:    */
  73:   private Arrays()
  74:   {
  75:   }
  76: 
  77: 
  78: // binarySearch
  79:   /**
  80:    * Perform a binary search of a byte array for a key. The array must be
  81:    * sorted (as by the sort() method) - if it is not, the behaviour of this
  82:    * method is undefined, and may be an infinite loop. If the array contains
  83:    * the key more than once, any one of them may be found. Note: although the
  84:    * specification allows for an infinite loop if the array is unsorted, it
  85:    * will not happen in this implementation.
  86:    *
  87:    * @param a the array to search (must be sorted)
  88:    * @param key the value to search for
  89:    * @return the index at which the key was found, or -n-1 if it was not
  90:    *         found, where n is the index of the first value higher than key or
  91:    *         a.length if there is no such value.
  92:    */
  93:   public static int binarySearch(byte[] a, byte key)
  94:   {
  95:     if (a.length == 0)
  96:       return -1;
  97:     return binarySearch(a, 0, a.length - 1, key);
  98:   }
  99: 
 100:   /**
 101:    * Perform a binary search of a range of a byte array for a key. The range
 102:    * must be sorted (as by the <code>sort(byte[], int, int)</code> method) -
 103:    * if it is not, the behaviour of this method is undefined, and may be an
 104:    * infinite loop. If the array contains the key more than once, any one of
 105:    * them may be found. Note: although the specification allows for an infinite
 106:    * loop if the array is unsorted, it will not happen in this implementation.
 107:    *
 108:    * @param a the array to search (must be sorted)
 109:    * @param low the lowest index to search from.
 110:    * @param hi the highest index to search to.
 111:    * @param key the value to search for
 112:    * @return the index at which the key was found, or -n-1 if it was not
 113:    *         found, where n is the index of the first value higher than key or
 114:    *         a.length if there is no such value.
 115:    * @throws IllegalArgumentException if <code>low > hi</code>
 116:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 117:    *                                        <code>hi > a.length</code>.
 118:    */
 119:   public static int binarySearch(byte[] a, int low, int hi, byte key)
 120:   {
 121:     if (low > hi)
 122:       throw new IllegalArgumentException("The start index is higher than " +
 123:                      "the finish index.");
 124:     if (low < 0 || hi > a.length)
 125:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 126:                            "of bounds.");
 127:     int mid = 0;
 128:     while (low <= hi)
 129:       {
 130:         mid = (low + hi) >>> 1;
 131:         final byte d = a[mid];
 132:         if (d == key)
 133:           return mid;
 134:         else if (d > key)
 135:           hi = mid - 1;
 136:         else
 137:           // This gets the insertion point right on the last loop.
 138:           low = ++mid;
 139:       }
 140:     return -mid - 1;
 141:   }
 142: 
 143:   /**
 144:    * Perform a binary search of a char array for a key. The array must be
 145:    * sorted (as by the sort() method) - if it is not, the behaviour of this
 146:    * method is undefined, and may be an infinite loop. If the array contains
 147:    * the key more than once, any one of them may be found. Note: although the
 148:    * specification allows for an infinite loop if the array is unsorted, it
 149:    * will not happen in this implementation.
 150:    *
 151:    * @param a the array to search (must be sorted)
 152:    * @param key the value to search for
 153:    * @return the index at which the key was found, or -n-1 if it was not
 154:    *         found, where n is the index of the first value higher than key or
 155:    *         a.length if there is no such value.
 156:    */
 157:   public static int binarySearch(char[] a, char key)
 158:   {
 159:     if (a.length == 0)
 160:       return -1;
 161:     return binarySearch(a, 0, a.length - 1, key);
 162:   }
 163: 
 164:   /**
 165:    * Perform a binary search of a range of a char array for a key. The range
 166:    * must be sorted (as by the <code>sort(char[], int, int)</code> method) -
 167:    * if it is not, the behaviour of this method is undefined, and may be an
 168:    * infinite loop. If the array contains the key more than once, any one of
 169:    * them may be found. Note: although the specification allows for an infinite
 170:    * loop if the array is unsorted, it will not happen in this implementation.
 171:    *
 172:    * @param a the array to search (must be sorted)
 173:    * @param low the lowest index to search from.
 174:    * @param hi the highest index to search to.
 175:    * @param key the value to search for
 176:    * @return the index at which the key was found, or -n-1 if it was not
 177:    *         found, where n is the index of the first value higher than key or
 178:    *         a.length if there is no such value.
 179:    * @throws IllegalArgumentException if <code>low > hi</code>
 180:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 181:    *                                        <code>hi > a.length</code>.
 182:    */
 183:   public static int binarySearch(char[] a, int low, int hi, char key)
 184:   {
 185:     if (low > hi)
 186:       throw new IllegalArgumentException("The start index is higher than " +
 187:                      "the finish index.");
 188:     if (low < 0 || hi > a.length)
 189:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 190:                            "of bounds.");
 191:     int mid = 0;
 192:     while (low <= hi)
 193:       {
 194:         mid = (low + hi) >>> 1;
 195:         final char d = a[mid];
 196:         if (d == key)
 197:           return mid;
 198:         else if (d > key)
 199:           hi = mid - 1;
 200:         else
 201:           // This gets the insertion point right on the last loop.
 202:           low = ++mid;
 203:       }
 204:     return -mid - 1;
 205:   }
 206: 
 207:   /**
 208:    * Perform a binary search of a short array for a key. The array must be
 209:    * sorted (as by the sort() method) - if it is not, the behaviour of this
 210:    * method is undefined, and may be an infinite loop. If the array contains
 211:    * the key more than once, any one of them may be found. Note: although the
 212:    * specification allows for an infinite loop if the array is unsorted, it
 213:    * will not happen in this implementation.
 214:    *
 215:    * @param a the array to search (must be sorted)
 216:    * @param key the value to search for
 217:    * @return the index at which the key was found, or -n-1 if it was not
 218:    *         found, where n is the index of the first value higher than key or
 219:    *         a.length if there is no such value.
 220:    */
 221:   public static int binarySearch(short[] a, short key)
 222:   {
 223:     if (a.length == 0)
 224:       return -1;
 225:     return binarySearch(a, 0, a.length - 1, key);
 226:   }
 227: 
 228:   /**
 229:    * Perform a binary search of a range of a short array for a key. The range
 230:    * must be sorted (as by the <code>sort(short[], int, int)</code> method) -
 231:    * if it is not, the behaviour of this method is undefined, and may be an
 232:    * infinite loop. If the array contains the key more than once, any one of
 233:    * them may be found. Note: although the specification allows for an infinite
 234:    * loop if the array is unsorted, it will not happen in this implementation.
 235:    *
 236:    * @param a the array to search (must be sorted)
 237:    * @param low the lowest index to search from.
 238:    * @param hi the highest index to search to.
 239:    * @param key the value to search for
 240:    * @return the index at which the key was found, or -n-1 if it was not
 241:    *         found, where n is the index of the first value higher than key or
 242:    *         a.length if there is no such value.
 243:    * @throws IllegalArgumentException if <code>low > hi</code>
 244:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 245:    *                                        <code>hi > a.length</code>.
 246:    */
 247:   public static int binarySearch(short[] a, int low, int hi, short key)
 248:   {
 249:     if (low > hi)
 250:       throw new IllegalArgumentException("The start index is higher than " +
 251:                      "the finish index.");
 252:     if (low < 0 || hi > a.length)
 253:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 254:                            "of bounds.");
 255:     int mid = 0;
 256:     while (low <= hi)
 257:       {
 258:         mid = (low + hi) >>> 1;
 259:         final short d = a[mid];
 260:         if (d == key)
 261:           return mid;
 262:         else if (d > key)
 263:           hi = mid - 1;
 264:         else
 265:           // This gets the insertion point right on the last loop.
 266:           low = ++mid;
 267:       }
 268:     return -mid - 1;
 269:   }
 270: 
 271:   /**
 272:    * Perform a binary search of an int array for a key. The array must be
 273:    * sorted (as by the sort() method) - if it is not, the behaviour of this
 274:    * method is undefined, and may be an infinite loop. If the array contains
 275:    * the key more than once, any one of them may be found. Note: although the
 276:    * specification allows for an infinite loop if the array is unsorted, it
 277:    * will not happen in this implementation.
 278:    *
 279:    * @param a the array to search (must be sorted)
 280:    * @param key the value to search for
 281:    * @return the index at which the key was found, or -n-1 if it was not
 282:    *         found, where n is the index of the first value higher than key or
 283:    *         a.length if there is no such value.
 284:    */
 285:   public static int binarySearch(int[] a, int key)
 286:   {
 287:     if (a.length == 0)
 288:       return -1;
 289:     return binarySearch(a, 0, a.length - 1, key);
 290:   }
 291: 
 292:   /**
 293:    * Perform a binary search of a range of an integer array for a key. The range
 294:    * must be sorted (as by the <code>sort(int[], int, int)</code> method) -
 295:    * if it is not, the behaviour of this method is undefined, and may be an
 296:    * infinite loop. If the array contains the key more than once, any one of
 297:    * them may be found. Note: although the specification allows for an infinite
 298:    * loop if the array is unsorted, it will not happen in this implementation.
 299:    *
 300:    * @param a the array to search (must be sorted)
 301:    * @param low the lowest index to search from.
 302:    * @param hi the highest index to search to.
 303:    * @param key the value to search for
 304:    * @return the index at which the key was found, or -n-1 if it was not
 305:    *         found, where n is the index of the first value higher than key or
 306:    *         a.length if there is no such value.
 307:    * @throws IllegalArgumentException if <code>low > hi</code>
 308:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 309:    *                                        <code>hi > a.length</code>.
 310:    */
 311:   public static int binarySearch(int[] a, int low, int hi, int key)
 312:   {
 313:     if (low > hi)
 314:       throw new IllegalArgumentException("The start index is higher than " +
 315:                      "the finish index.");
 316:     if (low < 0 || hi > a.length)
 317:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 318:                            "of bounds.");
 319:     int mid = 0;
 320:     while (low <= hi)
 321:       {
 322:         mid = (low + hi) >>> 1;
 323:         final int d = a[mid];
 324:         if (d == key)
 325:           return mid;
 326:         else if (d > key)
 327:           hi = mid - 1;
 328:         else
 329:           // This gets the insertion point right on the last loop.
 330:           low = ++mid;
 331:       }
 332:     return -mid - 1;
 333:   }
 334: 
 335:   /**
 336:    * Perform a binary search of a long array for a key. The array must be
 337:    * sorted (as by the sort() method) - if it is not, the behaviour of this
 338:    * method is undefined, and may be an infinite loop. If the array contains
 339:    * the key more than once, any one of them may be found. Note: although the
 340:    * specification allows for an infinite loop if the array is unsorted, it
 341:    * will not happen in this implementation.
 342:    *
 343:    * @param a the array to search (must be sorted)
 344:    * @param key the value to search for
 345:    * @return the index at which the key was found, or -n-1 if it was not
 346:    *         found, where n is the index of the first value higher than key or
 347:    *         a.length if there is no such value.
 348:    */
 349:   public static int binarySearch(long[] a, long key)
 350:   {
 351:     if (a.length == 0)
 352:       return -1;
 353:     return binarySearch(a, 0, a.length - 1, key);
 354:   }
 355: 
 356:   /**
 357:    * Perform a binary search of a range of a long array for a key. The range
 358:    * must be sorted (as by the <code>sort(long[], int, int)</code> method) -
 359:    * if it is not, the behaviour of this method is undefined, and may be an
 360:    * infinite loop. If the array contains the key more than once, any one of
 361:    * them may be found. Note: although the specification allows for an infinite
 362:    * loop if the array is unsorted, it will not happen in this implementation.
 363:    *
 364:    * @param a the array to search (must be sorted)
 365:    * @param low the lowest index to search from.
 366:    * @param hi the highest index to search to.
 367:    * @param key the value to search for
 368:    * @return the index at which the key was found, or -n-1 if it was not
 369:    *         found, where n is the index of the first value higher than key or
 370:    *         a.length if there is no such value.
 371:    * @throws IllegalArgumentException if <code>low > hi</code>
 372:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 373:    *                                        <code>hi > a.length</code>.
 374:    */
 375:   public static int binarySearch(long[] a, int low, int hi, long key)
 376:   {
 377:     if (low > hi)
 378:       throw new IllegalArgumentException("The start index is higher than " +
 379:                      "the finish index.");
 380:     if (low < 0 || hi > a.length)
 381:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 382:                            "of bounds.");
 383:     int mid = 0;
 384:     while (low <= hi)
 385:       {
 386:         mid = (low + hi) >>> 1;
 387:         final long d = a[mid];
 388:         if (d == key)
 389:           return mid;
 390:         else if (d > key)
 391:           hi = mid - 1;
 392:         else
 393:           // This gets the insertion point right on the last loop.
 394:           low = ++mid;
 395:       }
 396:     return -mid - 1;
 397:   }
 398: 
 399:   /**
 400:    * Perform a binary search of a float array for a key. The array must be
 401:    * sorted (as by the sort() method) - if it is not, the behaviour of this
 402:    * method is undefined, and may be an infinite loop. If the array contains
 403:    * the key more than once, any one of them may be found. Note: although the
 404:    * specification allows for an infinite loop if the array is unsorted, it
 405:    * will not happen in this implementation.
 406:    *
 407:    * @param a the array to search (must be sorted)
 408:    * @param key the value to search for
 409:    * @return the index at which the key was found, or -n-1 if it was not
 410:    *         found, where n is the index of the first value higher than key or
 411:    *         a.length if there is no such value.
 412:    */
 413:   public static int binarySearch(float[] a, float key)
 414:   {
 415:     if (a.length == 0)
 416:       return -1;
 417:     return binarySearch(a, 0, a.length - 1, key);
 418:   }
 419: 
 420:   /**
 421:    * Perform a binary search of a range of a float array for a key. The range
 422:    * must be sorted (as by the <code>sort(float[], int, int)</code> method) -
 423:    * if it is not, the behaviour of this method is undefined, and may be an
 424:    * infinite loop. If the array contains the key more than once, any one of
 425:    * them may be found. Note: although the specification allows for an infinite
 426:    * loop if the array is unsorted, it will not happen in this implementation.
 427:    *
 428:    * @param a the array to search (must be sorted)
 429:    * @param low the lowest index to search from.
 430:    * @param hi the highest index to search to.
 431:    * @param key the value to search for
 432:    * @return the index at which the key was found, or -n-1 if it was not
 433:    *         found, where n is the index of the first value higher than key or
 434:    *         a.length if there is no such value.
 435:    * @throws IllegalArgumentException if <code>low > hi</code>
 436:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 437:    *                                        <code>hi > a.length</code>.
 438:    */
 439:   public static int binarySearch(float[] a, int low, int hi, float key)
 440:   {
 441:     if (low > hi)
 442:       throw new IllegalArgumentException("The start index is higher than " +
 443:                      "the finish index.");
 444:     if (low < 0 || hi > a.length)
 445:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 446:                            "of bounds.");
 447:     // Must use Float.compare to take into account NaN, +-0.
 448:     int mid = 0;
 449:     while (low <= hi)
 450:       {
 451:         mid = (low + hi) >>> 1;
 452:         final int r = Float.compare(a[mid], key);
 453:         if (r == 0)
 454:           return mid;
 455:         else if (r > 0)
 456:           hi = mid - 1;
 457:         else
 458:           // This gets the insertion point right on the last loop
 459:           low = ++mid;
 460:       }
 461:     return -mid - 1;
 462:   }
 463: 
 464:   /**
 465:    * Perform a binary search of a double array for a key. The array must be
 466:    * sorted (as by the sort() method) - if it is not, the behaviour of this
 467:    * method is undefined, and may be an infinite loop. If the array contains
 468:    * the key more than once, any one of them may be found. Note: although the
 469:    * specification allows for an infinite loop if the array is unsorted, it
 470:    * will not happen in this implementation.
 471:    *
 472:    * @param a the array to search (must be sorted)
 473:    * @param key the value to search for
 474:    * @return the index at which the key was found, or -n-1 if it was not
 475:    *         found, where n is the index of the first value higher than key or
 476:    *         a.length if there is no such value.
 477:    */
 478:   public static int binarySearch(double[] a, double key)
 479:   {
 480:     if (a.length == 0)
 481:       return -1;
 482:     return binarySearch(a, 0, a.length - 1, key);
 483:   }
 484: 
 485:   /**
 486:    * Perform a binary search of a range of a double array for a key. The range
 487:    * must be sorted (as by the <code>sort(double[], int, int)</code> method) -
 488:    * if it is not, the behaviour of this method is undefined, and may be an
 489:    * infinite loop. If the array contains the key more than once, any one of
 490:    * them may be found. Note: although the specification allows for an infinite
 491:    * loop if the array is unsorted, it will not happen in this implementation.
 492:    *
 493:    * @param a the array to search (must be sorted)
 494:    * @param low the lowest index to search from.
 495:    * @param hi the highest index to search to.
 496:    * @param key the value to search for
 497:    * @return the index at which the key was found, or -n-1 if it was not
 498:    *         found, where n is the index of the first value higher than key or
 499:    *         a.length if there is no such value.
 500:    * @throws IllegalArgumentException if <code>low > hi</code>
 501:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 502:    *                                        <code>hi > a.length</code>.
 503:    */
 504:   public static int binarySearch(double[] a, int low, int hi, double key)
 505:   {
 506:     if (low > hi)
 507:       throw new IllegalArgumentException("The start index is higher than " +
 508:                      "the finish index.");
 509:     if (low < 0 || hi > a.length)
 510:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 511:                            "of bounds.");
 512:     // Must use Double.compare to take into account NaN, +-0.
 513:     int mid = 0;
 514:     while (low <= hi)
 515:       {
 516:         mid = (low + hi) >>> 1;
 517:         final int r = Double.compare(a[mid], key);
 518:         if (r == 0)
 519:           return mid;
 520:         else if (r > 0)
 521:           hi = mid - 1;
 522:         else
 523:           // This gets the insertion point right on the last loop
 524:           low = ++mid;
 525:       }
 526:     return -mid - 1;
 527:   }
 528: 
 529:   /**
 530:    * Perform a binary search of an Object array for a key, using the natural
 531:    * ordering of the elements. The array must be sorted (as by the sort()
 532:    * method) - if it is not, the behaviour of this method is undefined, and may
 533:    * be an infinite loop. Further, the key must be comparable with every item
 534:    * in the array. If the array contains the key more than once, any one of
 535:    * them may be found. Note: although the specification allows for an infinite
 536:    * loop if the array is unsorted, it will not happen in this (JCL)
 537:    * implementation.
 538:    *
 539:    * @param a the array to search (must be sorted)
 540:    * @param key the value to search for
 541:    * @return the index at which the key was found, or -n-1 if it was not
 542:    *         found, where n is the index of the first value higher than key or
 543:    *         a.length if there is no such value.
 544:    * @throws ClassCastException if key could not be compared with one of the
 545:    *         elements of a
 546:    * @throws NullPointerException if a null element in a is compared
 547:    */
 548:   public static int binarySearch(Object[] a, Object key)
 549:   {
 550:     if (a.length == 0)
 551:       return -1;
 552:     return binarySearch(a, key, null);
 553:   }
 554: 
 555:   /**
 556:    * Perform a binary search of a range of an Object array for a key. The range
 557:    * must be sorted (as by the <code>sort(Object[], int, int)</code> method) -
 558:    * if it is not, the behaviour of this method is undefined, and may be an
 559:    * infinite loop. If the array contains the key more than once, any one of
 560:    * them may be found. Note: although the specification allows for an infinite
 561:    * loop if the array is unsorted, it will not happen in this implementation.
 562:    *
 563:    * @param a the array to search (must be sorted)
 564:    * @param low the lowest index to search from.
 565:    * @param hi the highest index to search to.
 566:    * @param key the value to search for
 567:    * @return the index at which the key was found, or -n-1 if it was not
 568:    *         found, where n is the index of the first value higher than key or
 569:    *         a.length if there is no such value.
 570:    */
 571:   public static int binarySearch(Object[] a, int low, int hi, Object key)
 572:   {
 573:     return binarySearch(a, low, hi, key, null);
 574:   }
 575: 
 576:   /**
 577:    * Perform a binary search of an Object array for a key, using a supplied
 578:    * Comparator. The array must be sorted (as by the sort() method with the
 579:    * same Comparator) - if it is not, the behaviour of this method is
 580:    * undefined, and may be an infinite loop. Further, the key must be
 581:    * comparable with every item in the array. If the array contains the key
 582:    * more than once, any one of them may be found. Note: although the
 583:    * specification allows for an infinite loop if the array is unsorted, it
 584:    * will not happen in this (JCL) implementation.
 585:    *
 586:    * @param a the array to search (must be sorted)
 587:    * @param key the value to search for
 588:    * @param c the comparator by which the array is sorted; or null to
 589:    *        use the elements' natural order
 590:    * @return the index at which the key was found, or -n-1 if it was not
 591:    *         found, where n is the index of the first value higher than key or
 592:    *         a.length if there is no such value.
 593:    * @throws ClassCastException if key could not be compared with one of the
 594:    *         elements of a
 595:    * @throws NullPointerException if a null element is compared with natural
 596:    *         ordering (only possible when c is null)
 597:    */
 598:   public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)
 599:   {
 600:     if (a.length == 0)
 601:       return -1;
 602:     return binarySearch(a, 0, a.length - 1, key, c);
 603:   }
 604: 
 605:   /**
 606:    * Perform a binary search of a range of an Object array for a key using
 607:    * a {@link Comparator}. The range must be sorted (as by the
 608:    * <code>sort(Object[], int, int)</code> method) - if it is not, the
 609:    * behaviour of this method is undefined, and may be an infinite loop. If
 610:    * the array contains the key more than once, any one of them may be found.
 611:    * Note: although the specification allows for an infinite loop if the array
 612:    * is unsorted, it will not happen in this implementation.
 613:    *
 614:    * @param a the array to search (must be sorted)
 615:    * @param low the lowest index to search from.
 616:    * @param hi the highest index to search to.
 617:    * @param key the value to search for
 618:    * @param c the comparator by which the array is sorted; or null to
 619:    *        use the elements' natural order
 620:    * @return the index at which the key was found, or -n-1 if it was not
 621:    *         found, where n is the index of the first value higher than key or
 622:    *         a.length if there is no such value.
 623:    * @throws ClassCastException if key could not be compared with one of the
 624:    *         elements of a
 625:    * @throws IllegalArgumentException if <code>low > hi</code>
 626:    * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or
 627:    *                                        <code>hi > a.length</code>.
 628:    */
 629:   public static <T> int binarySearch(T[] a, int low, int hi, T key,
 630:                      Comparator<? super T> c)
 631:   {
 632:     if (low > hi)
 633:       throw new IllegalArgumentException("The start index is higher than " +
 634:                      "the finish index.");
 635:     if (low < 0 || hi > a.length)
 636:       throw new ArrayIndexOutOfBoundsException("One of the indices is out " +
 637:                            "of bounds.");
 638:     int mid = 0;
 639:     while (low <= hi)
 640:       {
 641:         mid = (low + hi) >>> 1;
 642:     // NOTE: Please keep the order of a[mid] and key.  Although
 643:     // not required by the specs, the RI has it in this order as
 644:     // well, and real programs (erroneously) depend on it.
 645:         final int d = Collections.compare(a[mid], key, c);
 646:         if (d == 0)
 647:           return mid;
 648:         else if (d > 0)
 649:           hi = mid - 1;
 650:         else
 651:           // This gets the insertion point right on the last loop
 652:           low = ++mid;
 653:       }
 654:     return -mid - 1;
 655:   }
 656: 
 657: 
 658: // equals
 659:   /**
 660:    * Compare two boolean arrays for equality.
 661:    *
 662:    * @param a1 the first array to compare
 663:    * @param a2 the second array to compare
 664:    * @return true if a1 and a2 are both null, or if a2 is of the same length
 665:    *         as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
 666:    */
 667:   public static boolean equals(boolean[] a1, boolean[] a2)
 668:   {
 669:     // Quick test which saves comparing elements of the same array, and also
 670:     // catches the case that both are null.
 671:     if (a1 == a2)
 672:       return true;
 673: 
 674:     if (null == a1 || null == a2)
 675:       return false;
 676:     
 677:     // If they're the same length, test each element
 678:     if (a1.length == a2.length)
 679:       {
 680:     int i = a1.length;
 681:     while (--i >= 0)
 682:       if (a1[i] != a2[i])
 683:         return false;
 684:     return true;
 685:       }
 686:     return false;
 687:   }
 688: 
 689:   /**
 690:    * Compare two byte arrays for equality.
 691:    *
 692:    * @param a1 the first array to compare
 693:    * @param a2 the second array to compare
 694:    * @return true if a1 and a2 are both null, or if a2 is of the same length
 695:    *         as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
 696:    */
 697:   public static boolean equals(byte[] a1, byte[] a2)
 698:   {
 699:     // Quick test which saves comparing elements of the same array, and also
 700:     // catches the case that both are null.
 701:     if (a1 == a2)
 702:       return true;
 703: 
 704:     if (null == a1 || null == a2)
 705:       return false;
 706: 
 707:     // If they're the same length, test each element
 708:     if (a1.length == a2.length)
 709:       {
 710:     int i = a1.length;
 711:     while (--i >= 0)
 712:       if (a1[i] != a2[i])
 713:         return false;
 714:     return true;
 715:       }
 716:     return false;
 717:   }
 718: 
 719:   /**
 720:    * Compare two char arrays for equality.
 721:    *
 722:    * @param a1 the first array to compare
 723:    * @param a2 the second array to compare
 724:    * @return true if a1 and a2 are both null, or if a2 is of the same length
 725:    *         as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
 726:    */
 727:   public static boolean equals(char[] a1, char[] a2)
 728:   {
 729:     // Quick test which saves comparing elements of the same array, and also
 730:     // catches the case that both are null.
 731:     if (a1 == a2)
 732:       return true;
 733: 
 734:     if (null == a1 || null == a2)
 735:       return false;
 736:     
 737:     // If they're the same length, test each element
 738:     if (a1.length == a2.length)
 739:       {
 740:     int i = a1.length;
 741:     while (--i >= 0)
 742:       if (a1[i] != a2[i])
 743:         return false;
 744:     return true;
 745:       }
 746:     return false;
 747:   }
 748: 
 749:   /**
 750:    * Compare two short arrays for equality.
 751:    *
 752:    * @param a1 the first array to compare
 753:    * @param a2 the second array to compare
 754:    * @return true if a1 and a2 are both null, or if a2 is of the same length
 755:    *         as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
 756:    */
 757:   public static boolean equals(short[] a1, short[] a2)
 758:   {
 759:     // Quick test which saves comparing elements of the same array, and also
 760:     // catches the case that both are null.
 761:     if (a1 == a2)
 762:       return true;
 763: 
 764:     if (null == a1 || null == a2)
 765:       return false;
 766: 
 767:     // If they're the same length, test each element
 768:     if (a1.length == a2.length)
 769:       {
 770:     int i = a1.length;
 771:     while (--i >= 0)
 772:       if (a1[i] != a2[i])
 773:         return false;
 774:     return true;
 775:       }
 776:     return false;
 777:   }
 778: 
 779:   /**
 780:    * Compare two int arrays for equality.
 781:    *
 782:    * @param a1 the first array to compare
 783:    * @param a2 the second array to compare
 784:    * @return true if a1 and a2 are both null, or if a2 is of the same length
 785:    *         as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
 786:    */
 787:   public static boolean equals(int[] a1, int[] a2)
 788:   {
 789:     // Quick test which saves comparing elements of the same array, and also
 790:     // catches the case that both are null.
 791:     if (a1 == a2)
 792:       return true;
 793: 
 794:     if (null == a1 || null == a2)
 795:       return false;
 796: 
 797:     // If they're the same length, test each element
 798:     if (a1.length == a2.length)
 799:       {
 800:     int i = a1.length;
 801:     while (--i >= 0)
 802:       if (a1[i] != a2[i])
 803:         return false;
 804:     return true;
 805:       }
 806:     return false;
 807:   }
 808: 
 809:   /**
 810:    * Compare two long arrays for equality.
 811:    *
 812:    * @param a1