source: trunk/gcc/libjava/java/util/Arrays.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 71.3 KB
Line 
1/* Arrays.java -- Utility class with methods to operate on arrays
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.util;
40
41import java.io.Serializable;
42import java.lang.reflect.Array;
43
44/**
45 * This class contains various static utility methods performing operations on
46 * arrays, and a method to provide a List "view" of an array to facilitate
47 * using arrays with Collection-based APIs. All methods throw a
48 * {@link NullPointerException} if the parameter array is null.
49 * <p>
50 *
51 * Implementations may use their own algorithms, but must obey the general
52 * properties; for example, the sort must be stable and n*log(n) complexity.
53 * Sun's implementation of sort, and therefore ours, is a tuned quicksort,
54 * adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering a Sort
55 * Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265
56 * (November 1993). This algorithm offers n*log(n) performance on many data
57 * sets that cause other quicksorts to degrade to quadratic performance.
58 *
59 * @author Original author unknown
60 * @author Bryce McKinlay
61 * @author Eric Blake <ebb9@email.byu.edu>
62 * @see Comparable
63 * @see Comparator
64 * @since 1.2
65 * @status updated to 1.4
66 */
67public class Arrays
68{
69 /**
70 * This class is non-instantiable.
71 */
72 private Arrays()
73 {
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 int low = 0;
96 int hi = a.length - 1;
97 int mid = 0;
98 while (low <= hi)
99 {
100 mid = (low + hi) >> 1;
101 final byte d = a[mid];
102 if (d == key)
103 return mid;
104 else if (d > key)
105 hi = mid - 1;
106 else
107 // This gets the insertion point right on the last loop.
108 low = ++mid;
109 }
110 return -mid - 1;
111 }
112
113 /**
114 * Perform a binary search of a char array for a key. The array must be
115 * sorted (as by the sort() method) - if it is not, the behaviour of this
116 * method is undefined, and may be an infinite loop. If the array contains
117 * the key more than once, any one of them may be found. Note: although the
118 * specification allows for an infinite loop if the array is unsorted, it
119 * will not happen in this implementation.
120 *
121 * @param a the array to search (must be sorted)
122 * @param key the value to search for
123 * @return the index at which the key was found, or -n-1 if it was not
124 * found, where n is the index of the first value higher than key or
125 * a.length if there is no such value.
126 */
127 public static int binarySearch(char[] a, char key)
128 {
129 int low = 0;
130 int hi = a.length - 1;
131 int mid = 0;
132 while (low <= hi)
133 {
134 mid = (low + hi) >> 1;
135 final char d = a[mid];
136 if (d == key)
137 return mid;
138 else if (d > key)
139 hi = mid - 1;
140 else
141 // This gets the insertion point right on the last loop.
142 low = ++mid;
143 }
144 return -mid - 1;
145 }
146
147 /**
148 * Perform a binary search of a short array for a key. The array must be
149 * sorted (as by the sort() method) - if it is not, the behaviour of this
150 * method is undefined, and may be an infinite loop. If the array contains
151 * the key more than once, any one of them may be found. Note: although the
152 * specification allows for an infinite loop if the array is unsorted, it
153 * will not happen in this implementation.
154 *
155 * @param a the array to search (must be sorted)
156 * @param key the value to search for
157 * @return the index at which the key was found, or -n-1 if it was not
158 * found, where n is the index of the first value higher than key or
159 * a.length if there is no such value.
160 */
161 public static int binarySearch(short[] a, short key)
162 {
163 int low = 0;
164 int hi = a.length - 1;
165 int mid = 0;
166 while (low <= hi)
167 {
168 mid = (low + hi) >> 1;
169 final short d = a[mid];
170 if (d == key)
171 return mid;
172 else if (d > key)
173 hi = mid - 1;
174 else
175 // This gets the insertion point right on the last loop.
176 low = ++mid;
177 }
178 return -mid - 1;
179 }
180
181 /**
182 * Perform a binary search of an int array for a key. The array must be
183 * sorted (as by the sort() method) - if it is not, the behaviour of this
184 * method is undefined, and may be an infinite loop. If the array contains
185 * the key more than once, any one of them may be found. Note: although the
186 * specification allows for an infinite loop if the array is unsorted, it
187 * will not happen in this implementation.
188 *
189 * @param a the array to search (must be sorted)
190 * @param key the value to search for
191 * @return the index at which the key was found, or -n-1 if it was not
192 * found, where n is the index of the first value higher than key or
193 * a.length if there is no such value.
194 */
195 public static int binarySearch(int[] a, int key)
196 {
197 int low = 0;
198 int hi = a.length - 1;
199 int mid = 0;
200 while (low <= hi)
201 {
202 mid = (low + hi) >> 1;
203 final int d = a[mid];
204 if (d == key)
205 return mid;
206 else if (d > key)
207 hi = mid - 1;
208 else
209 // This gets the insertion point right on the last loop.
210 low = ++mid;
211 }
212 return -mid - 1;
213 }
214
215 /**
216 * Perform a binary search of a long array for a key. The array must be
217 * sorted (as by the sort() method) - if it is not, the behaviour of this
218 * method is undefined, and may be an infinite loop. If the array contains
219 * the key more than once, any one of them may be found. Note: although the
220 * specification allows for an infinite loop if the array is unsorted, it
221 * will not happen in this implementation.
222 *
223 * @param a the array to search (must be sorted)
224 * @param key the value to search for
225 * @return the index at which the key was found, or -n-1 if it was not
226 * found, where n is the index of the first value higher than key or
227 * a.length if there is no such value.
228 */
229 public static int binarySearch(long[] a, long key)
230 {
231 int low = 0;
232 int hi = a.length - 1;
233 int mid = 0;
234 while (low <= hi)
235 {
236 mid = (low + hi) >> 1;
237 final long d = a[mid];
238 if (d == key)
239 return mid;
240 else if (d > key)
241 hi = mid - 1;
242 else
243 // This gets the insertion point right on the last loop.
244 low = ++mid;
245 }
246 return -mid - 1;
247 }
248
249 /**
250 * Perform a binary search of a float array for a key. The array must be
251 * sorted (as by the sort() method) - if it is not, the behaviour of this
252 * method is undefined, and may be an infinite loop. If the array contains
253 * the key more than once, any one of them may be found. Note: although the
254 * specification allows for an infinite loop if the array is unsorted, it
255 * will not happen in this implementation.
256 *
257 * @param a the array to search (must be sorted)
258 * @param key the value to search for
259 * @return the index at which the key was found, or -n-1 if it was not
260 * found, where n is the index of the first value higher than key or
261 * a.length if there is no such value.
262 */
263 public static int binarySearch(float[] a, float key)
264 {
265 // Must use Float.compare to take into account NaN, +-0.
266 int low = 0;
267 int hi = a.length - 1;
268 int mid = 0;
269 while (low <= hi)
270 {
271 mid = (low + hi) >> 1;
272 final int r = Float.compare(a[mid], key);
273 if (r == 0)
274 return mid;
275 else if (r > 0)
276 hi = mid - 1;
277 else
278 // This gets the insertion point right on the last loop
279 low = ++mid;
280 }
281 return -mid - 1;
282 }
283
284 /**
285 * Perform a binary search of a double array for a key. The array must be
286 * sorted (as by the sort() method) - if it is not, the behaviour of this
287 * method is undefined, and may be an infinite loop. If the array contains
288 * the key more than once, any one of them may be found. Note: although the
289 * specification allows for an infinite loop if the array is unsorted, it
290 * will not happen in this implementation.
291 *
292 * @param a the array to search (must be sorted)
293 * @param key the value to search for
294 * @return the index at which the key was found, or -n-1 if it was not
295 * found, where n is the index of the first value higher than key or
296 * a.length if there is no such value.
297 */
298 public static int binarySearch(double[] a, double key)
299 {
300 // Must use Double.compare to take into account NaN, +-0.
301 int low = 0;
302 int hi = a.length - 1;
303 int mid = 0;
304 while (low <= hi)
305 {
306 mid = (low + hi) >> 1;
307 final int r = Double.compare(a[mid], key);
308 if (r == 0)
309 return mid;
310 else if (r > 0)
311 hi = mid - 1;
312 else
313 // This gets the insertion point right on the last loop
314 low = ++mid;
315 }
316 return -mid - 1;
317 }
318
319 /**
320 * Perform a binary search of an Object array for a key, using the natural
321 * ordering of the elements. The array must be sorted (as by the sort()
322 * method) - if it is not, the behaviour of this method is undefined, and may
323 * be an infinite loop. Further, the key must be comparable with every item
324 * in the array. If the array contains the key more than once, any one of
325 * them may be found. Note: although the specification allows for an infinite
326 * loop if the array is unsorted, it will not happen in this (JCL)
327 * implementation.
328 *
329 * @param a the array to search (must be sorted)
330 * @param key the value to search for
331 * @return the index at which the key was found, or -n-1 if it was not
332 * found, where n is the index of the first value higher than key or
333 * a.length if there is no such value.
334 * @throws ClassCastException if key could not be compared with one of the
335 * elements of a
336 * @throws NullPointerException if a null element in a is compared
337 */
338 public static int binarySearch(Object[] a, Object key)
339 {
340 return binarySearch(a, key, null);
341 }
342
343 /**
344 * Perform a binary search of an Object array for a key, using a supplied
345 * Comparator. The array must be sorted (as by the sort() method with the
346 * same Comparator) - if it is not, the behaviour of this method is
347 * undefined, and may be an infinite loop. Further, the key must be
348 * comparable with every item in the array. If the array contains the key
349 * more than once, any one of them may be found. Note: although the
350 * specification allows for an infinite loop if the array is unsorted, it
351 * will not happen in this (JCL) implementation.
352 *
353 * @param a the array to search (must be sorted)
354 * @param key the value to search for
355 * @param c the comparator by which the array is sorted; or null to
356 * use the elements' natural order
357 * @return the index at which the key was found, or -n-1 if it was not
358 * found, where n is the index of the first value higher than key or
359 * a.length if there is no such value.
360 * @throws ClassCastException if key could not be compared with one of the
361 * elements of a
362 * @throws NullPointerException if a null element is compared with natural
363 * ordering (only possible when c is null)
364 */
365 public static int binarySearch(Object[] a, Object key, Comparator c)
366 {
367 int low = 0;
368 int hi = a.length - 1;
369 int mid = 0;
370 while (low <= hi)
371 {
372 mid = (low + hi) >> 1;
373 final int d = Collections.compare(key, a[mid], c);
374 if (d == 0)
375 return mid;
376 else if (d < 0)
377 hi = mid - 1;
378 else
379 // This gets the insertion point right on the last loop
380 low = ++mid;
381 }
382 return -mid - 1;
383 }
384
385
386
387// equals
388 /**
389 * Compare two boolean arrays for equality.
390 *
391 * @param a1 the first array to compare
392 * @param a2 the second array to compare
393 * @return true if a1 and a2 are both null, or if a2 is of the same length
394 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
395 */
396 public static boolean equals(boolean[] a1, boolean[] a2)
397 {
398 // Quick test which saves comparing elements of the same array, and also
399 // catches the case that both are null.
400 if (a1 == a2)
401 return true;
402
403 try
404 {
405 // If they're the same length, test each element
406 if (a1.length == a2.length)
407 {
408 int i = a1.length;
409 while (--i >= 0)
410 if (a1[i] != a2[i])
411 return false;
412 return true;
413 }
414 }
415 catch (NullPointerException e)
416 {
417 // If one is null, we get a harmless NullPointerException
418 }
419
420 return false;
421 }
422
423 /**
424 * Compare two byte arrays for equality.
425 *
426 * @param a1 the first array to compare
427 * @param a2 the second array to compare
428 * @return true if a1 and a2 are both null, or if a2 is of the same length
429 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
430 */
431 public static boolean equals(byte[] a1, byte[] a2)
432 {
433 // Quick test which saves comparing elements of the same array, and also
434 // catches the case that both are null.
435 if (a1 == a2)
436 return true;
437
438 try
439 {
440 // If they're the same length, test each element
441 if (a1.length == a2.length)
442 {
443 int i = a1.length;
444 while (--i >= 0)
445 if (a1[i] != a2[i])
446 return false;
447 return true;
448 }
449 }
450 catch (NullPointerException e)
451 {
452 // If one is null, we get a harmless NullPointerException
453 }
454 return false;
455 }
456
457 /**
458 * Compare two char arrays for equality.
459 *
460 * @param a1 the first array to compare
461 * @param a2 the second array to compare
462 * @return true if a1 and a2 are both null, or if a2 is of the same length
463 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
464 */
465 public static boolean equals(char[] a1, char[] a2)
466 {
467 // Quick test which saves comparing elements of the same array, and also
468 // catches the case that both are null.
469 if (a1 == a2)
470 return true;
471
472 try
473 {
474 // If they're the same length, test each element
475 if (a1.length == a2.length)
476 {
477 int i = a1.length;
478 while (--i >= 0)
479 if (a1[i] != a2[i])
480 return false;
481 return true;
482 }
483 }
484 catch (NullPointerException e)
485 {
486 // If one is null, we get a harmless NullPointerException
487 }
488 return false;
489 }
490
491 /**
492 * Compare two short arrays for equality.
493 *
494 * @param a1 the first array to compare
495 * @param a2 the second array to compare
496 * @return true if a1 and a2 are both null, or if a2 is of the same length
497 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
498 */
499 public static boolean equals(short[] a1, short[] a2)
500 {
501 // Quick test which saves comparing elements of the same array, and also
502 // catches the case that both are null.
503 if (a1 == a2)
504 return true;
505
506 try
507 {
508 // If they're the same length, test each element
509 if (a1.length == a2.length)
510 {
511 int i = a1.length;
512 while (--i >= 0)
513 if (a1[i] != a2[i])
514 return false;
515 return true;
516 }
517 }
518 catch (NullPointerException e)
519 {
520 // If one is null, we get a harmless NullPointerException
521 }
522 return false;
523 }
524
525 /**
526 * Compare two int arrays for equality.
527 *
528 * @param a1 the first array to compare
529 * @param a2 the second array to compare
530 * @return true if a1 and a2 are both null, or if a2 is of the same length
531 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
532 */
533 public static boolean equals(int[] a1, int[] a2)
534 {
535 // Quick test which saves comparing elements of the same array, and also
536 // catches the case that both are null.
537 if (a1 == a2)
538 return true;
539
540 try
541 {
542 // If they're the same length, test each element
543 if (a1.length == a2.length)
544 {
545 int i = a1.length;
546 while (--i >= 0)
547 if (a1[i] != a2[i])
548 return false;
549 return true;
550 }
551 }
552 catch (NullPointerException e)
553 {
554 // If one is null, we get a harmless NullPointerException
555 }
556 return false;
557 }
558
559 /**
560 * Compare two long arrays for equality.
561 *
562 * @param a1 the first array to compare
563 * @param a2 the second array to compare
564 * @return true if a1 and a2 are both null, or if a2 is of the same length
565 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
566 */
567 public static boolean equals(long[] a1, long[] a2)
568 {
569 // Quick test which saves comparing elements of the same array, and also
570 // catches the case that both are null.
571 if (a1 == a2)
572 return true;
573
574 try
575 {
576 // If they're the same length, test each element
577 if (a1.length == a2.length)
578 {
579 int i = a1.length;
580 while (--i >= 0)
581 if (a1[i] != a2[i])
582 return false;
583 return true;
584 }
585 }
586 catch (NullPointerException e)
587 {
588 // If one is null, we get a harmless NullPointerException
589 }
590 return false;
591 }
592
593 /**
594 * Compare two float arrays for equality.
595 *
596 * @param a1 the first array to compare
597 * @param a2 the second array to compare
598 * @return true if a1 and a2 are both null, or if a2 is of the same length
599 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
600 */
601 public static boolean equals(float[] a1, float[] a2)
602 {
603 // Quick test which saves comparing elements of the same array, and also
604 // catches the case that both are null.
605 if (a1 == a2)
606 return true;
607
608 // Must use Float.compare to take into account NaN, +-0.
609 try
610 {
611 // If they're the same length, test each element
612 if (a1.length == a2.length)
613 {
614 int i = a1.length;
615 while (--i >= 0)
616 if (Float.compare(a1[i], a2[i]) != 0)
617 return false;
618 return true;
619 }
620 }
621 catch (NullPointerException e)
622 {
623 // If one is null, we get a harmless NullPointerException
624 }
625 return false;
626 }
627
628 /**
629 * Compare two double arrays for equality.
630 *
631 * @param a1 the first array to compare
632 * @param a2 the second array to compare
633 * @return true if a1 and a2 are both null, or if a2 is of the same length
634 * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
635 */
636 public static boolean equals(double[] a1, double[] a2)
637 {
638 // Quick test which saves comparing elements of the same array, and also
639 // catches the case that both are null.
640 if (a1 == a2)
641 return true;
642
643 // Must use Double.compare to take into account NaN, +-0.
644 try
645 {
646 // If they're the same length, test each element
647 if (a1.length == a2.length)
648 {
649 int i = a1.length;
650 while (--i >= 0)
651 if (Double.compare(a1[i], a2[i]) != 0)
652 return false;
653 return true;
654 }
655 }
656 catch (NullPointerException e)
657 {
658 // If one is null, we get a harmless NullPointerException
659 }
660 return false;
661 }
662
663 /**
664 * Compare two Object arrays for equality.
665 *
666 * @param a1 the first array to compare
667 * @param a2 the second array to compare
668 * @return true if a1 and a2 are both null, or if a1 is of the same length
669 * as a2, and for each 0 <= i < a.length, a1[i] == null ?
670 * a2[i] == null : a1[i].equals(a2[i]).
671 */
672 public static boolean equals(Object[] a1, Object[] a2)
673 {
674 // Quick test which saves comparing elements of the same array, and also
675 // catches the case that both are null.
676 if (a1 == a2)
677 return true;
678
679 try
680 {
681 // If they're the same length, test each element
682 if (a1.length == a2.length)
683 {
684 int i = a1.length;
685 while (--i >= 0)
686 if (! AbstractCollection.equals(a1[i], a2[i]))
687 return false;
688 return true;
689 }
690 }
691 catch (NullPointerException e)
692 {
693 // If one is null, we get a harmless NullPointerException
694 }
695 return false;
696 }
697
698
699
700// fill
701 /**
702 * Fill an array with a boolean value.
703 *
704 * @param a the array to fill
705 * @param val the value to fill it with
706 */
707 public static void fill(boolean[] a, boolean val)
708 {
709 fill(a, 0, a.length, val);
710 }
711
712 /**
713 * Fill a range of an array with a boolean value.
714 *
715 * @param a the array to fill
716 * @param fromIndex the index to fill from, inclusive
717 * @param toIndex the index to fill to, exclusive
718 * @param val the value to fill with
719 * @throws IllegalArgumentException if fromIndex &gt; toIndex
720 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
721 * || toIndex &gt; a.length
722 */
723 public static void fill(boolean[] a, int fromIndex, int toIndex, boolean val)
724 {
725 if (fromIndex > toIndex)
726 throw new IllegalArgumentException();
727 for (int i = fromIndex; i < toIndex; i++)
728 a[i] = val;
729 }
730
731 /**
732 * Fill an array with a byte value.
733 *
734 * @param a the array to fill
735 * @param val the value to fill it with
736 */
737 public static void fill(byte[] a, byte val)
738 {
739 fill(a, 0, a.length, val);
740 }
741
742 /**
743 * Fill a range of an array with a byte value.
744 *
745 * @param a the array to fill
746 * @param fromIndex the index to fill from, inclusive
747 * @param toIndex the index to fill to, exclusive
748 * @param val the value to fill with
749 * @throws IllegalArgumentException if fromIndex &gt; toIndex
750 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
751 * || toIndex &gt; a.length
752 */
753 public static void fill(byte[] a, int fromIndex, int toIndex, byte val)
754 {
755 if (fromIndex > toIndex)
756 throw new IllegalArgumentException();
757 for (int i = fromIndex; i < toIndex; i++)
758 a[i] = val;
759 }
760
761 /**
762 * Fill an array with a char value.
763 *
764 * @param a the array to fill
765 * @param val the value to fill it with
766 */
767 public static void fill(char[] a, char val)
768 {
769 fill(a, 0, a.length, val);
770 }
771
772 /**
773 * Fill a range of an array with a char value.
774 *
775 * @param a the array to fill
776 * @param fromIndex the index to fill from, inclusive
777 * @param toIndex the index to fill to, exclusive
778 * @param val the value to fill with
779 * @throws IllegalArgumentException if fromIndex &gt; toIndex
780 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
781 * || toIndex &gt; a.length
782 */
783 public static void fill(char[] a, int fromIndex, int toIndex, char val)
784 {
785 if (fromIndex > toIndex)
786 throw new IllegalArgumentException();
787 for (int i = fromIndex; i < toIndex; i++)
788 a[i] = val;
789 }
790
791 /**
792 * Fill an array with a short value.
793 *
794 * @param a the array to fill
795 * @param val the value to fill it with
796 */
797 public static void fill(short[] a, short val)
798 {
799 fill(a, 0, a.length, val);
800 }
801
802 /**
803 * Fill a range of an array with a short value.
804 *
805 * @param a the array to fill
806 * @param fromIndex the index to fill from, inclusive
807 * @param toIndex the index to fill to, exclusive
808 * @param val the value to fill with
809 * @throws IllegalArgumentException if fromIndex &gt; toIndex
810 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
811 * || toIndex &gt; a.length
812 */
813 public static void fill(short[] a, int fromIndex, int toIndex, short val)
814 {
815 if (fromIndex > toIndex)
816 throw new IllegalArgumentException();
817 for (int i = fromIndex; i < toIndex; i++)
818 a[i] = val;
819 }
820
821 /**
822 * Fill an array with an int value.
823 *
824 * @param a the array to fill
825 * @param val the value to fill it with
826 */
827 public static void fill(int[] a, int val)
828 {
829 fill(a, 0, a.length, val);
830 }
831
832 /**
833 * Fill a range of an array with an int value.
834 *
835 * @param a the array to fill
836 * @param fromIndex the index to fill from, inclusive
837 * @param toIndex the index to fill to, exclusive
838 * @param val the value to fill with
839 * @throws IllegalArgumentException if fromIndex &gt; toIndex
840 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
841 * || toIndex &gt; a.length
842 */
843 public static void fill(int[] a, int fromIndex, int toIndex, int val)
844 {
845 if (fromIndex > toIndex)
846 throw new IllegalArgumentException();
847 for (int i = fromIndex; i < toIndex; i++)
848 a[i] = val;
849 }
850
851 /**
852 * Fill an array with a long value.
853 *
854 * @param a the array to fill
855 * @param val the value to fill it with
856 */
857 public static void fill(long[] a, long val)
858 {
859 fill(a, 0, a.length, val);
860 }
861
862 /**
863 * Fill a range of an array with a long value.
864 *
865 * @param a the array to fill
866 * @param fromIndex the index to fill from, inclusive
867 * @param toIndex the index to fill to, exclusive
868 * @param val the value to fill with
869 * @throws IllegalArgumentException if fromIndex &gt; toIndex
870 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
871 * || toIndex &gt; a.length
872 */
873 public static void fill(long[] a, int fromIndex, int toIndex, long val)
874 {
875 if (fromIndex > toIndex)
876 throw new IllegalArgumentException();
877 for (int i = fromIndex; i < toIndex; i++)
878 a[i] = val;
879 }
880
881 /**
882 * Fill an array with a float value.
883 *
884 * @param a the array to fill
885 * @param val the value to fill it with
886 */
887 public static void fill(float[] a, float val)
888 {
889 fill(a, 0, a.length, val);
890 }
891
892 /**
893 * Fill a range of an array with a float value.
894 *
895 * @param a the array to fill
896 * @param fromIndex the index to fill from, inclusive
897 * @param toIndex the index to fill to, exclusive
898 * @param val the value to fill with
899 * @throws IllegalArgumentException if fromIndex &gt; toIndex
900 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
901 * || toIndex &gt; a.length
902 */
903 public static void fill(float[] a, int fromIndex, int toIndex, float val)
904 {
905 if (fromIndex > toIndex)
906 throw new IllegalArgumentException();
907 for (int i = fromIndex; i < toIndex; i++)
908 a[i] = val;
909 }
910
911 /**
912 * Fill an array with a double value.
913 *
914 * @param a the array to fill
915 * @param val the value to fill it with
916 */
917 public static void fill(double[] a, double val)
918 {
919 fill(a, 0, a.length, val);
920 }
921
922 /**
923 * Fill a range of an array with a double value.
924 *
925 * @param a the array to fill
926 * @param fromIndex the index to fill from, inclusive
927 * @param toIndex the index to fill to, exclusive
928 * @param val the value to fill with
929 * @throws IllegalArgumentException if fromIndex &gt; toIndex
930 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
931 * || toIndex &gt; a.length
932 */
933 public static void fill(double[] a, int fromIndex, int toIndex, double val)
934 {
935 if (fromIndex > toIndex)
936 throw new IllegalArgumentException();
937 for (int i = fromIndex; i < toIndex; i++)
938 a[i] = val;
939 }
940
941 /**
942 * Fill an array with an Object value.
943 *
944 * @param a the array to fill
945 * @param val the value to fill it with
946 * @throws ClassCastException if val is not an instance of the element
947 * type of a.
948 */
949 public static void fill(Object[] a, Object val)
950 {
951 fill(a, 0, a.length, val);
952 }
953
954 /**
955 * Fill a range of an array with an Object value.
956 *
957 * @param a the array to fill
958 * @param fromIndex the index to fill from, inclusive
959 * @param toIndex the index to fill to, exclusive
960 * @param val the value to fill with
961 * @throws ClassCastException if val is not an instance of the element
962 * type of a.
963 * @throws IllegalArgumentException if fromIndex &gt; toIndex
964 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
965 * || toIndex &gt; a.length
966 */
967 public static void fill(Object[] a, int fromIndex, int toIndex, Object val)
968 {
969 if (fromIndex > toIndex)
970 throw new IllegalArgumentException();
971 for (int i = fromIndex; i < toIndex; i++)
972 a[i] = val;
973 }
974
975
976
977// sort
978 // Thanks to Paul Fisher <rao@gnu.org> for finding this quicksort algorithm
979 // as specified by Sun and porting it to Java. The algorithm is an optimised
980 // quicksort, as described in Jon L. Bentley and M. Douglas McIlroy's
981 // "Engineering a Sort Function", Software-Practice and Experience, Vol.
982 // 23(11) P. 1249-1265 (November 1993). This algorithm gives n*log(n)
983 // performance on many arrays that would take quadratic time with a standard
984 // quicksort.
985
986 /**
987 * Performs a stable sort on the elements, arranging them according to their
988 * natural order.
989 *
990 * @param a the byte array to sort
991 */
992 public static void sort(byte[] a)
993 {
994 qsort(a, 0, a.length);
995 }
996
997 /**
998 * Performs a stable sort on the elements, arranging them according to their
999 * natural order.
1000 *
1001 * @param a the byte array to sort
1002 * @param fromIndex the first index to sort (inclusive)
1003 * @param toIndex the last index to sort (exclusive)
1004 * @throws IllegalArgumentException if fromIndex &gt; toIndex
1005 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
1006 * || toIndex &gt; a.length
1007 */
1008 public static void sort(byte[] a, int fromIndex, int toIndex)
1009 {
1010 if (fromIndex > toIndex)
1011 throw new IllegalArgumentException();
1012 qsort(a, fromIndex, toIndex - fromIndex);
1013 }
1014
1015 /**
1016 * Finds the index of the median of three array elements.
1017 *
1018 * @param a the first index
1019 * @param b the second index
1020 * @param c the third index
1021 * @param d the array
1022 * @return the index (a, b, or c) which has the middle value of the three
1023 */
1024 private static int med3(int a, int b, int c, byte[] d)
1025 {
1026 return (d[a] < d[b]
1027 ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a)
1028 : (d[b] > d[c] ? b : d[a] > d[c] ? c : a));
1029 }
1030
1031 /**
1032 * Swaps the elements at two locations of an array
1033 *
1034 * @param i the first index
1035 * @param j the second index
1036 * @param a the array
1037 */
1038 private static void swap(int i, int j, byte[] a)
1039 {
1040 byte c = a[i];
1041 a[i] = a[j];
1042 a[j] = c;
1043 }
1044
1045 /**
1046 * Swaps two ranges of an array.
1047 *
1048 * @param i the first range start
1049 * @param j the second range start
1050 * @param n the element count
1051 * @param a the array
1052 */
1053 private static void vecswap(int i, int j, int n, byte[] a)
1054 {
1055 for ( ; n > 0; i++, j++, n--)
1056 swap(i, j, a);
1057 }
1058
1059 /**
1060 * Performs a recursive modified quicksort.
1061 *
1062 * @param a the array to sort
1063 * @param from the start index (inclusive)
1064 * @param count the number of elements to sort
1065 */
1066 private static void qsort(byte[] array, int from, int count)
1067 {
1068 // Use an insertion sort on small arrays.
1069 if (count <= 7)
1070 {
1071 for (int i = from + 1; i < from + count; i++)
1072 for (int j = i; j > 0 && array[j - 1] > array[j]; j--)
1073 swap(j, j - 1, array);
1074 return;
1075 }
1076
1077 // Determine a good median element.
1078 int mid = count / 2;
1079 int lo = from;
1080 int hi = from + count - 1;
1081
1082 if (count > 40)
1083 { // big arrays, pseudomedian of 9
1084 int s = count / 8;
1085 lo = med3(lo, lo + s, lo + 2 * s, array);
1086 mid = med3(mid - s, mid, mid + s, array);
1087 hi = med3(hi - 2 * s, hi - s, hi, array);
1088 }
1089 mid = med3(lo, mid, hi, array);
1090
1091 int a, b, c, d;
1092 int comp;
1093
1094 // Pull the median element out of the fray, and use it as a pivot.
1095 swap(from, mid, array);
1096 a = b = from;
1097 c = d = from + count - 1;
1098
1099 // Repeatedly move b and c to each other, swapping elements so
1100 // that all elements before index b are less than the pivot, and all
1101 // elements after index c are greater than the pivot. a and b track
1102 // the elements equal to the pivot.
1103 while (true)
1104 {
1105 while (b <= c && (comp = array[b] - array[from]) <= 0)
1106 {
1107 if (comp == 0)
1108 {
1109 swap(a, b, array);
1110 a++;
1111 }
1112 b++;
1113 }
1114 while (c >= b && (comp = array[c] - array[from]) >= 0)
1115 {
1116 if (comp == 0)
1117 {
1118 swap(c, d, array);
1119 d--;
1120 }
1121 c--;
1122 }
1123 if (b > c)
1124 break;
1125 swap(b, c, array);
1126 b++;
1127 c--;
1128 }
1129
1130 // Swap pivot(s) back in place, the recurse on left and right sections.
1131 hi = from + count;
1132 int span;
1133 span = Math.min(a - from, b - a);
1134 vecswap(from, b - span, span, array);
1135
1136 span = Math.min(d - c, hi - d - 1);
1137 vecswap(b, hi - span, span, array);
1138
1139 span = b - a;
1140 if (span > 1)
1141 qsort(array, from, span);
1142
1143 span = d - c;
1144 if (span > 1)
1145 qsort(array, hi - span, span);
1146 }
1147
1148 /**
1149 * Performs a stable sort on the elements, arranging them according to their
1150 * natural order.
1151 *
1152 * @param a the char array to sort
1153 */
1154 public static void sort(char[] a)
1155 {
1156 qsort(a, 0, a.length);
1157 }
1158
1159 /**
1160 * Performs a stable sort on the elements, arranging them according to their
1161 * natural order.
1162 *
1163 * @param a the char array to sort
1164 * @param fromIndex the first index to sort (inclusive)
1165 * @param toIndex the last index to sort (exclusive)
1166 * @throws IllegalArgumentException if fromIndex &gt; toIndex
1167 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
1168 * || toIndex &gt; a.length
1169 */
1170 public static void sort(char[] a, int fromIndex, int toIndex)
1171 {
1172 if (fromIndex > toIndex)
1173 throw new IllegalArgumentException();
1174 qsort(a, fromIndex, toIndex - fromIndex);
1175 }
1176
1177 /**
1178 * Finds the index of the median of three array elements.
1179 *
1180 * @param a the first index
1181 * @param b the second index
1182 * @param c the third index
1183 * @param d the array
1184 * @return the index (a, b, or c) which has the middle value of the three
1185 */
1186 private static int med3(int a, int b, int c, char[] d)
1187 {
1188 return (d[a] < d[b]
1189 ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a)
1190 : (d[b] > d[c] ? b : d[a] > d[c] ? c : a));
1191 }
1192
1193 /**
1194 * Swaps the elements at two locations of an array
1195 *
1196 * @param i the first index
1197 * @param j the second index
1198 * @param a the array
1199 */
1200 private static void swap(int i, int j, char[] a)
1201 {
1202 char c = a[i];
1203 a[i] = a[j];
1204 a[j] = c;
1205 }
1206
1207 /**
1208 * Swaps two ranges of an array.
1209 *
1210 * @param i the first range start
1211 * @param j the second range start
1212 * @param n the element count
1213 * @param a the array
1214 */
1215 private static void vecswap(int i, int j, int n, char[] a)
1216 {
1217 for ( ; n > 0; i++, j++, n--)
1218 swap(i, j, a);
1219 }
1220
1221 /**
1222 * Performs a recursive modified quicksort.
1223 *
1224 * @param a the array to sort
1225 * @param from the start index (inclusive)
1226 * @param count the number of elements to sort
1227 */
1228 private static void qsort(char[] array, int from, int count)
1229 {
1230 // Use an insertion sort on small arrays.
1231 if (count <= 7)
1232 {
1233 for (int i = from + 1; i < from + count; i++)
1234 for (int j = i; j > 0 && array[j - 1] > array[j]; j--)
1235 swap(j, j - 1, array);
1236 return;
1237 }
1238
1239 // Determine a good median element.
1240 int mid = count / 2;
1241 int lo = from;
1242 int hi = from + count - 1;
1243
1244 if (count > 40)
1245 { // big arrays, pseudomedian of 9
1246 int s = count / 8;
1247 lo = med3(lo, lo + s, lo + 2 * s, array);
1248 mid = med3(mid - s, mid, mid + s, array);
1249 hi = med3(hi - 2 * s, hi - s, hi, array);
1250 }
1251 mid = med3(lo, mid, hi, array);
1252
1253 int a, b, c, d;
1254 int comp;
1255
1256 // Pull the median element out of the fray, and use it as a pivot.
1257 swap(from, mid, array);
1258 a = b = from;
1259 c = d = from + count - 1;
1260
1261 // Repeatedly move b and c to each other, swapping elements so
1262 // that all elements before index b are less than the pivot, and all
1263 // elements after index c are greater than the pivot. a and b track
1264 // the elements equal to the pivot.
1265 while (true)
1266 {
1267 while (b <= c && (comp = array[b] - array[from]) <= 0)
1268 {
1269 if (comp == 0)
1270 {
1271 swap(a, b, array);
1272 a++;
1273 }
1274 b++;
1275 }
1276 while (c >= b && (comp = array[c] - array[from]) >= 0)
1277 {
1278 if (comp == 0)
1279 {
1280 swap(c, d, array);
1281 d--;
1282 }
1283 c--;
1284 }
1285 if (b > c)
1286 break;
1287 swap(b, c, array);
1288 b++;
1289 c--;
1290 }
1291
1292 // Swap pivot(s) back in place, the recurse on left and right sections.
1293 hi = from + count;
1294 int span;
1295 span = Math.min(a - from, b - a);
1296 vecswap(from, b - span, span, array);
1297
1298 span = Math.min(d - c, hi - d - 1);
1299 vecswap(b, hi - span, span, array);
1300
1301 span = b - a;
1302 if (span > 1)
1303 qsort(array, from, span);
1304
1305 span = d - c;
1306 if (span > 1)
1307 qsort(array, hi - span, span);
1308 }
1309
1310 /**
1311 * Performs a stable sort on the elements, arranging them according to their
1312 * natural order.
1313 *
1314 * @param a the short array to sort
1315 */
1316 public static void sort(short[] a)
1317 {
1318 qsort(a, 0, a.length);
1319 }
1320
1321 /**
1322 * Performs a stable sort on the elements, arranging them according to their
1323 * natural order.
1324 *
1325 * @param a the short array to sort
1326 * @param fromIndex the first index to sort (inclusive)
1327 * @param toIndex the last index to sort (exclusive)
1328 * @throws IllegalArgumentException if fromIndex &gt; toIndex
1329 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
1330 * || toIndex &gt; a.length
1331 */
1332 public static void sort(short[] a, int fromIndex, int toIndex)
1333 {
1334 if (fromIndex > toIndex)
1335 throw new IllegalArgumentException();
1336 qsort(a, fromIndex, toIndex - fromIndex);
1337 }
1338
1339 /**
1340 * Finds the index of the median of three array elements.
1341 *
1342 * @param a the first index
1343 * @param b the second index
1344 * @param c the third index
1345 * @param d the array
1346 * @return the index (a, b, or c) which has the middle value of the three
1347 */
1348 private static int med3(int a, int b, int c, short[] d)
1349 {
1350 return (d[a] < d[b]
1351 ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a)
1352 : (d[b] > d[c] ? b : d[a] > d[c] ? c : a));
1353 }
1354
1355 /**
1356 * Swaps the elements at two locations of an array
1357 *
1358 * @param i the first index
1359 * @param j the second index
1360 * @param a the array
1361 */
1362 private static void swap(int i, int j, short[] a)
1363 {
1364 short c = a[i];
1365 a[i] = a[j];
1366 a[j] = c;
1367 }
1368
1369 /**
1370 * Swaps two ranges of an array.
1371 *
1372 * @param i the first range start
1373 * @param j the second range start
1374 * @param n the element count
1375 * @param a the array
1376 */
1377 private static void vecswap(int i, int j, int n, short[] a)
1378 {
1379 for ( ; n > 0; i++, j++, n--)
1380 swap(i, j, a);
1381 }
1382
1383 /**
1384 * Performs a recursive modified quicksort.
1385 *
1386 * @param a the array to sort
1387 * @param from the start index (inclusive)
1388 * @param count the number of elements to sort
1389 */
1390 private static void qsort(short[] array, int from, int count)
1391 {
1392 // Use an insertion sort on small arrays.
1393 if (count <= 7)
1394 {
1395 for (int i = from + 1; i < from + count; i++)
1396 for (int j = i; j > 0 && array[j - 1] > array[j]; j--)
1397 swap(j, j - 1, array);
1398 return;
1399 }
1400
1401 // Determine a good median element.
1402 int mid = count / 2;
1403 int lo = from;
1404 int hi = from + count - 1;
1405
1406 if (count > 40)
1407 { // big arrays, pseudomedian of 9
1408 int s = count / 8;
1409 lo = med3(lo, lo + s, lo + 2 * s, array);
1410 mid = med3(mid - s, mid, mid + s, array);
1411 hi = med3(hi - 2 * s, hi - s, hi, array);
1412 }
1413 mid = med3(lo, mid, hi, array);
1414
1415 int a, b, c, d;
1416 int comp;
1417
1418 // Pull the median element out of the fray, and use it as a pivot.
1419 swap(from, mid, array);
1420 a = b = from;
1421 c = d = from + count - 1;
1422
1423 // Repeatedly move b and c to each other, swapping elements so
1424 // that all elements before index b are less than the pivot, and all
1425 // elements after index c are greater than the pivot. a and b track
1426 // the elements equal to the pivot.
1427 while (true)
1428 {
1429 while (b <= c && (comp = array[b] - array[from]) <= 0)
1430 {
1431 if (comp == 0)
1432 {
1433 swap(a, b, array);
1434 a++;
1435 }
1436 b++;
1437 }
1438 while (c >= b && (comp = array[c] - array[from]) >= 0)
1439 {
1440 if (comp == 0)
1441 {
1442 swap(c, d, array);
1443 d--;
1444 }
1445 c--;
1446 }
1447 if (b > c)
1448 break;
1449 swap(b, c, array);
1450 b++;
1451 c--;
1452 }
1453
1454 // Swap pivot(s) back in place, the recurse on left and right sections.
1455 hi = from + count;
1456 int span;
1457 span = Math.min(a - from, b - a);
1458 vecswap(from, b - span, span, array);
1459
1460 span = Math.min(d - c, hi - d - 1);
1461 vecswap(b, hi - span, span, array);
1462
1463 span = b - a;
1464 if (span > 1)
1465 qsort(array, from, span);
1466
1467 span = d - c;
1468 if (span > 1)
1469 qsort(array, hi - span, span);
1470 }
1471
1472 /**
1473 * Performs a stable sort on the elements, arranging them according to their
1474 * natural order.
1475 *
1476 * @param a the int array to sort
1477 */
1478 public static void sort(int[] a)
1479 {
1480 qsort(a, 0, a.length);
1481 }
1482
1483 /**
1484 * Performs a stable sort on the elements, arranging them according to their
1485 * natural order.
1486 *
1487 * @param a the int array to sort
1488 * @param fromIndex the first index to sort (inclusive)
1489 * @param toIndex the last index to sort (exclusive)
1490 * @throws IllegalArgumentException if fromIndex &gt; toIndex
1491 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
1492 * || toIndex &gt; a.length
1493 */
1494 public static void sort(int[] a, int fromIndex, int toIndex)
1495 {
1496 if (fromIndex > toIndex)
1497 throw new IllegalArgumentException();
1498 qsort(a, fromIndex, toIndex - fromIndex);
1499 }
1500
1501 /**
1502 * Finds the index of the median of three array elements.
1503 *
1504 * @param a the first index
1505 * @param b the second index
1506 * @param c the third index
1507 * @param d the array
1508 * @return the index (a, b, or c) which has the middle value of the three
1509 */
1510 private static int med3(int a, int b, int c, int[] d)
1511 {
1512 return (d[a] < d[b]
1513 ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a)
1514 : (d[b] > d[c] ? b : d[a] > d[c] ? c : a));
1515 }
1516
1517 /**
1518 * Swaps the elements at two locations of an array
1519 *
1520 * @param i the first index
1521 * @param j the second index
1522 * @param a the array
1523 */
1524 private static void swap(int i, int j, int[] a)
1525 {
1526 int c = a[i];
1527 a[i] = a[j];
1528 a[j] = c;
1529 }
1530
1531 /**
1532 * Swaps two ranges of an array.
1533 *
1534 * @param i the first range start
1535 * @param j the second range start
1536 * @param n the element count
1537 * @param a the array
1538 */
1539 private static void vecswap(int i, int j, int n, int[] a)
1540 {
1541 for ( ; n > 0; i++, j++, n--)
1542 swap(i, j, a);
1543 }
1544
1545 /**
1546 * Compares two integers in natural order, since a - b is inadequate.
1547 *
1548 * @param a the first int
1549 * @param b the second int
1550 * @return &lt; 0, 0, or &gt; 0 accorting to the comparison
1551 */
1552 private static int compare(int a, int b)
1553 {
1554 return a < b ? -1 : a == b ? 0 : 1;
1555 }
1556
1557 /**
1558 * Performs a recursive modified quicksort.
1559 *
1560 * @param a the array to sort
1561 * @param from the start index (inclusive)
1562 * @param count the number of elements to sort
1563 */
1564 private static void qsort(int[] array, int from, int count)
1565 {
1566 // Use an insertion sort on small arrays.
1567 if (count <= 7)
1568 {
1569 for (int i = from + 1; i < from + count; i++)
1570 for (int j = i; j > 0 && array[j - 1] > array[j]; j--)
1571 swap(j, j - 1, array);
1572 return;
1573 }
1574
1575 // Determine a good median element.
1576 int mid = count / 2;
1577 int lo = from;
1578 int hi = from + count - 1;
1579
1580 if (count > 40)
1581 { // big arrays, pseudomedian of 9
1582 int s = count / 8;
1583 lo = med3(lo, lo + s, lo + 2 * s, array);
1584 mid = med3(mid - s, mid, mid + s, array);
1585 hi = med3(hi - 2 * s, hi - s, hi, array);
1586 }
1587 mid = med3(lo, mid, hi, array);
1588
1589 int a, b, c, d;
1590 int comp;
1591
1592 // Pull the median element out of the fray, and use it as a pivot.
1593 swap(from, mid, array);
1594 a = b = from;
1595 c = d = from + count - 1;
1596
1597 // Repeatedly move b and c to each other, swapping elements so
1598 // that all elements before index b are less than the pivot, and all
1599 // elements after index c are greater than the pivot. a and b track
1600 // the elements equal to the pivot.
1601 while (true)
1602 {
1603 while (b <= c && (comp = compare(array[b], array[from])) <= 0)
1604 {
1605 if (comp == 0)
1606 {
1607 swap(a, b, array);
1608 a++;
1609 }
1610 b++;
1611 }
1612 while (c >= b && (comp = compare(array[c], array[from])) >= 0)
1613 {
1614 if (comp == 0)
1615 {
1616 swap(c, d, array);
1617 d--;
1618 }
1619 c--;
1620 }
1621 if (b > c)
1622 break;
1623 swap(b, c, array);
1624 b++;
1625 c--;
1626 }
1627
1628 // Swap pivot(s) back in place, the recurse on left and right sections.
1629 hi = from + count;
1630 int span;
1631 span = Math.min(a - from, b - a);
1632 vecswap(from, b - span, span, array);
1633
1634 span = Math.min(d - c, hi - d - 1);
1635 vecswap(b, hi - span, span, array);
1636
1637 span = b - a;
1638 if (span > 1)
1639 qsort(array, from, span);
1640
1641 span = d - c;
1642 if (span > 1)
1643 qsort(array, hi - span, span);
1644 }
1645
1646 /**
1647 * Performs a stable sort on the elements, arranging them according to their
1648 * natural order.
1649 *
1650 * @param a the long array to sort
1651 */
1652 public static void sort(long[] a)
1653 {
1654 qsort(a, 0, a.length);
1655 }
1656
1657 /**
1658 * Performs a stable sort on the elements, arranging them according to their
1659 * natural order.
1660 *
1661 * @param a the long array to sort
1662 * @param fromIndex the first index to sort (inclusive)
1663 * @param toIndex the last index to sort (exclusive)
1664 * @throws IllegalArgumentException if fromIndex &gt; toIndex
1665 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
1666 * || toIndex &gt; a.length
1667 */
1668 public static void sort(long[] a, int fromIndex, int toIndex)
1669 {
1670 if (fromIndex > toIndex)
1671 throw new IllegalArgumentException();
1672 qsort(a, fromIndex, toIndex - fromIndex);
1673 }
1674
1675 /**
1676 * Finds the index of the median of three array elements.
1677 *
1678 * @param a the first index
1679 * @param b the second index
1680 * @param c the third index
1681 * @param d the array
1682 * @return the index (a, b, or c) which has the middle value of the three
1683 */
1684 private static int med3(int a, int b, int c, long[] d)
1685 {
1686 return (d[a] < d[b]
1687 ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a)
1688 : (d[b] > d[c] ? b : d[a] > d[c] ? c : a));
1689 }
1690
1691 /**
1692 * Swaps the elements at two locations of an array
1693 *
1694 * @param i the first index
1695 * @param j the second index
1696 * @param a the array
1697 */
1698 private static void swap(int i, int j, long[] a)
1699 {
1700 long c = a[i];
1701 a[i] = a[j];
1702 a[j] = c;
1703 }
1704
1705 /**
1706 * Swaps two ranges of an array.
1707 *
1708 * @param i the first range start
1709 * @param j the second range start
1710 * @param n the element count
1711 * @param a the array
1712 */
1713 private static void vecswap(int i, int j, int n, long[] a)
1714 {
1715 for ( ; n > 0; i++, j++, n--)
1716 swap(i, j, a);
1717 }
1718
1719 /**
1720 * Compares two longs in natural order, since a - b is inadequate.
1721 *
1722 * @param a the first long
1723 * @param b the second long
1724 * @return &lt; 0, 0, or &gt; 0 accorting to the comparison
1725 */
1726 private static int compare(long a, long b)
1727 {
1728 return a < b ? -1 : a == b ? 0 : 1;
1729 }
1730
1731 /**
1732 * Performs a recursive modified quicksort.
1733 *
1734 * @param a the array to sort
1735 * @param from the start index (inclusive)
1736 * @param count the number of elements to sort
1737 */
1738 private static void qsort(long[] array, int from, int count)
1739 {
1740 // Use an insertion sort on small arrays.
1741 if (count <= 7)
1742 {
1743 for (int i = from + 1; i < from + count; i++)
1744 for (int j = i; j > 0 && array[j - 1] > array[j]; j--)
1745 swap(j, j - 1, array);
1746 return;
1747 }
1748
1749 // Determine a good median element.
1750 int mid = count / 2;
1751 int lo = from;
1752 int hi = from + count - 1;
1753
1754 if (count > 40)
1755 { // big arrays, pseudomedian of 9
1756 int s = count / 8;
1757 lo = med3(lo, lo + s, lo + 2 * s, array);
1758 mid = med3(mid - s, mid, mid + s, array);
1759 hi = med3(hi - 2 * s, hi - s, hi, array);
1760 }
1761 mid = med3(lo, mid, hi, array);
1762
1763 int a, b, c, d;
1764 int comp;
1765
1766 // Pull the median element out of the fray, and use it as a pivot.
1767 swap(from, mid, array);
1768 a = b = from;
1769 c = d = from + count - 1;
1770
1771 // Repeatedly move b and c to each other, swapping elements so
1772 // that all elements before index b are less than the pivot, and all
1773 // elements after index c are greater than the pivot. a and b track
1774 // the elements equal to the pivot.
1775 while (true)
1776 {
1777 while (b <= c && (comp = compare(array[b], array[from])) <= 0)
1778 {
1779 if (comp == 0)
1780 {
1781 swap(a, b, array);
1782 a++;
1783 }
1784 b++;
1785 }
1786 while (c >= b && (comp = compare(array[c], array[from])) >= 0)
1787 {
1788 if (comp == 0)
1789 {
1790 swap(c, d, array);
1791 d--;
1792 }
1793 c--;
1794 }
1795 if (b > c)
1796 break;
1797 swap(b, c, array);
1798 b++;
1799 c--;
1800 }
1801
1802 // Swap pivot(s) back in place, the recurse on left and right sections.
1803 hi = from + count;
1804 int span;
1805 span = Math.min(a - from, b - a);
1806 vecswap(from, b - span, span, array);
1807
1808 span = Math.min(d - c, hi - d - 1);
1809 vecswap(b, hi - span, span, array);
1810
1811 span = b - a;
1812 if (span > 1)
1813 qsort(array, from, span);
1814
1815 span = d - c;
1816 if (span > 1)
1817 qsort(array, hi - span, span);
1818 }
1819
1820 /**
1821 * Performs a stable sort on the elements, arranging them according to their
1822 * natural order.
1823 *
1824 * @param a the float array to sort
1825 */
1826 public static void sort(float[] a)
1827 {
1828 qsort(a, 0, a.length);
1829 }
1830
1831 /**
1832 * Performs a stable sort on the elements, arranging them according to their
1833 * natural order.
1834 *
1835 * @param a the float array to sort
1836 * @param fromIndex the first index to sort (inclusive)
1837 * @param toIndex the last index to sort (exclusive)
1838 * @throws IllegalArgumentException if fromIndex &gt; toIndex
1839 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
1840 * || toIndex &gt; a.length
1841 */
1842 public static void sort(float[] a, int fromIndex, int toIndex)
1843 {
1844 if (fromIndex > toIndex)
1845 throw new IllegalArgumentException();
1846 qsort(a, fromIndex, toIndex - fromIndex);
1847 }
1848
1849 /**
1850 * Finds the index of the median of three array elements.
1851 *
1852 * @param a the first index
1853 * @param b the second index
1854 * @param c the third index
1855 * @param d the array
1856 * @return the index (a, b, or c) which has the middle value of the three
1857 */
1858 private static int med3(int a, int b, int c, float[] d)
1859 {
1860 return (Float.compare(d[a], d[b]) < 0
1861 ? (Float.compare(d[b], d[c]) < 0 ? b
1862 : Float.compare(d[a], d[c]) < 0 ? c : a)
1863 : (Float.compare(d[b], d[c]) > 0 ? b
1864 : Float.compare(d[a], d[c]) > 0 ? c : a));
1865 }
1866
1867 /**
1868 * Swaps the elements at two locations of an array
1869 *
1870 * @param i the first index
1871 * @param j the second index
1872 * @param a the array
1873 */
1874 private static void swap(int i, int j, float[] a)
1875 {
1876 float c = a[i];
1877 a[i] = a[j];
1878 a[j] = c;
1879 }
1880
1881 /**
1882 * Swaps two ranges of an array.
1883 *
1884 * @param i the first range start
1885 * @param j the second range start
1886 * @param n the element count
1887 * @param a the array
1888 */
1889 private static void vecswap(int i, int j, int n, float[] a)
1890 {
1891 for ( ; n > 0; i++, j++, n--)
1892 swap(i, j, a);
1893 }
1894
1895 /**
1896 * Performs a recursive modified quicksort.
1897 *
1898 * @param a the array to sort
1899 * @param from the start index (inclusive)
1900 * @param count the number of elements to sort
1901 */
1902 private static void qsort(float[] array, int from, int count)
1903 {
1904 // Use an insertion sort on small arrays.
1905 if (count <= 7)
1906 {
1907 for (int i = from + 1; i < from + count; i++)
1908 for (int j = i;
1909 j > 0 && Float.compare(array[j - 1], array[j]) > 0;
1910 j--)
1911 {
1912 swap(j, j - 1, array);
1913 }
1914 return;
1915 }
1916
1917 // Determine a good median element.
1918 int mid = count / 2;
1919 int lo = from;
1920 int hi = from + count - 1;
1921
1922 if (count > 40)
1923 { // big arrays, pseudomedian of 9
1924 int s = count / 8;
1925 lo = med3(lo, lo + s, lo + 2 * s, array);
1926 mid = med3(mid - s, mid, mid + s, array);
1927 hi = med3(hi - 2 * s, hi - s, hi, array);
1928 }
1929 mid = med3(lo, mid, hi, array);
1930
1931 int a, b, c, d;
1932 int comp;
1933
1934 // Pull the median element out of the fray, and use it as a pivot.
1935 swap(from, mid, array);
1936 a = b = from;
1937 c = d = from + count - 1;
1938
1939 // Repeatedly move b and c to each other, swapping elements so
1940 // that all elements before index b are less than the pivot, and all
1941 // elements after index c are greater than the pivot. a and b track
1942 // the elements equal to the pivot.
1943 while (true)
1944 {
1945 while (b <= c && (comp = Float.compare(array[b], array[from])) <= 0)
1946 {
1947 if (comp == 0)
1948 {
1949 swap(a, b, array);
1950 a++;
1951 }
1952 b++;
1953 }
1954 while (c >= b && (comp = Float.compare(array[c], array[from])) >= 0)
1955 {
1956 if (comp == 0)
1957 {
1958 swap(c, d, array);
1959 d--;
1960 }
1961 c--;
1962 }
1963 if (b > c)
1964 break;
1965 swap(b, c, array);
1966 b++;
1967 c--;
1968 }
1969
1970 // Swap pivot(s) back in place, the recurse on left and right sections.
1971 hi = from + count;
1972 int span;
1973 span = Math.min(a - from, b - a);
1974 vecswap(from, b - span, span, array);
1975
1976 span = Math.min(d - c, hi - d - 1);
1977 vecswap(b, hi - span, span, array);
1978
1979 span = b - a;
1980 if (span > 1)
1981 qsort(array, from, span);
1982
1983 span = d - c;
1984 if (span > 1)
1985 qsort(array, hi - span, span);
1986 }
1987
1988 /**
1989 * Performs a stable sort on the elements, arranging them according to their
1990 * natural order.
1991 *
1992 * @param a the double array to sort
1993 */
1994 public static void sort(double[] a)
1995 {
1996 qsort(a, 0, a.length);
1997 }
1998
1999 /**
2000 * Performs a stable sort on the elements, arranging them according to their
2001 * natural order.
2002 *
2003 * @param a the double array to sort
2004 * @param fromIndex the first index to sort (inclusive)
2005 * @param toIndex the last index to sort (exclusive)
2006 * @throws IllegalArgumentException if fromIndex &gt; toIndex
2007 * @throws ArrayIndexOutOfBoundsException if fromIndex &lt; 0
2008 * || toIndex &gt; a.length
2009 */
2010 public static void sort(double[] a, int fromIndex, int toIndex)
2011 {
2012 if (fromIndex > toIndex)
2013 throw new IllegalArgumentException();
2014 qsort(a, fromIndex, toIndex - fromIndex);
2015 }
2016
2017 /**
2018 * Finds the index of the median of three array elements.
2019 *
2020 * @param a the first index
2021 * @param b the second index
2022 * @param c the third index
2023 * @param d the array
2024 * @return the index (a, b, or c) which has the middle value of the three
2025 */
2026 private static int med3(int a, int b, int c, double[] d)
2027 {
2028 return (Double.compare(d[a], d[b]) < 0
2029 ? (Double.compare(d[b], d[c]) < 0 ? b
2030 : Double.compare(d[a], d[c]) < 0 ? c : a)
2031 : (Double.compare(d[b], d[c]) > 0 ? b
2032 : Double.compare(d[a], d[c]) > 0 ? c : a));
2033 }
2034
2035 /**
2036 * Swaps the elements at two locations of an array
2037 *
2038 * @param i the first index
2039 * @param j the second index
2040 * @param a the array
2041 */
2042 private static void swap(int i, int j, double[] a)
2043 {
2044 double c = a[i];
2045 a[i] = a[j];
2046 a[j] = c;
2047 }
2048
2049 /**
2050 * Swaps two ranges of an array.
2051 *
2052 * @param i the first range start
2053 * @param j the second range start
2054 * @param n the element count
2055 * @param a the array
2056 */
2057 private static void vecswap(int i, int j, int n, double[] a)
2058 {
2059 for ( ; n > 0; i++, j++, n--)
2060 swap(i, j, a);
2061 }
2062
2063 /**
2064 * Performs a recursive modified quicksort.
2065 *
2066 * @param a the array to sort
2067 * @param from the start index (inclusive)
2068 * @param count the number of elements to sort
2069 */
2070 private static void qsort(double[] array, int from, int count)
2071 {
2072 // Use an insertion sort on small arrays.
2073 if (count <= 7)
2074 {
2075 for (int i = from + 1; i < from + count; i++)
2076 for (int j = i;
2077 j > 0 && Double.compare(array[j - 1], array[j]) > 0;
2078 j--)
2079 {
2080 swap(j, j - 1, array);
2081 }
2082 return;
2083 }
2084
2085 // Determine a good median element.
2086 int mid = count / 2;
2087 int lo = from;
2088 int hi = from + count - 1;
2089
2090 if (count > 40)
2091 { // big arrays, pseudomedian of 9
2092 int s = count / 8;
2093 lo = med3(lo, lo + s, lo + 2 * s, array);
2094 mid = med3(mid - s, mid, mid + s, array);
2095 hi = med3(hi - 2 * s, hi - s, hi, array);
2096 }
2097 mid = med3(lo, mid, hi, array);
2098
2099 int a, b, c, d;
2100 int comp;
2101
2102 // Pull the median element out of the fray, and use it as a pivot.
2103 swap(from, mid, array);
2104 a = b = from;
2105 c = d = from + count - 1;
2106
2107 // Repeatedly move b and c to each other, swapping elements so
2108 // that all elements before index b are less than the pivot, and all
2109 // elements after index c are greater than the pivot. a and b track
2110 // the elements equal to the pivot.
2111 while (true)
2112 {
2113 while (b <= c && (comp = Double.compare(array[b], array[from])) <= 0)
2114 {
2115 if (comp == 0)
2116 {
2117 swap(a, b, array);
2118 a++;
2119 }
2120 b++;
2121 }
2122 while (c >= b && (comp = Double.compare(array[c], array[from])) >= 0)
2123 {
2124 if (comp == 0)
2125 {
2126 swap(c, d, array);
2127 d--;
2128 }
2129 c--;
2130 }
2131 if (b > c)
2132 break;
2133 swap(b, c, array);
2134 b++;
2135 c--;
2136 }
2137
2138 // Swap pivot(s) back in place, the recurse on left and right sections.
2139 hi = from + count;
2140 int span;
2141 span = Math.min(a - from, b - a);
2142 vecswap(from, b - span, span, array);
2143
2144 span = Math.min(d - c, hi - d - 1);
2145 vecswap(b, hi - span, span, array);
2146
2147 span = b - a;
2148 if (span > 1)
2149 qsort(array, from, span);
2150
2151 span = d - c;
2152 if (span > 1)
2153 qsort(array, hi - span, span);
2154 }
2155
2156 /**
2157 * Sort an array of Objects according to their natural ordering. The sort is
2158 * guaranteed to be stable, that is, equal elements will not be reordered.
2159 * The sort algorithm is a mergesort with the merge omitted if the last
2160 * element of one half comes before the first element of the other half. This
2161 * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a
2162 * copy of the array.
2163 *
2164 * @param a the array to be sorted
2165 * @throws ClassCastException if any two elements are not mutually
2166 * comparable
2167 * @throws NullPointerException if an element is null (since
2168 * null.compareTo cannot work)
2169 * @see Comparable
2170 */
2171 public static void sort(Object[] a)
2172 {
2173 sort(a, 0, a.length, null);
2174 }
2175
2176 /**
2177 * Sort an array of Objects according to a Comparator. The sort is
2178 * guaranteed to be stable, that is, equal elements will not be reordered.
2179 * The sort algorithm is a mergesort with the merge omitted if the last
2180 * element of one half comes before the first element of the other half. This
2181 * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a
2182 * copy of the array.
2183 *
2184 * @param a the array to be sorted
2185 * @param c a Comparator to use in sorting the array; or null to indicate
2186 * the elements' natural order
2187 * @throws ClassCastException if any two elements are not mutually
2188 * comparable by the Comparator provided
2189 * @throws NullPointerException if a null element is compared with natural
2190 * ordering (only possible when c is null)
2191 */
2192 public static void sort(Object[] a, Comparator c)
2193 {
2194 sort(a, 0, a.length, c);
2195 }
2196
2197 /**
2198 * Sort an array of Objects according to their natural ordering. The sort is
2199 * guaranteed to be stable, that is, equal elements will not be reordered.
2200 * The sort algorithm is a mergesort with the merge omitted if the last
2201 * element of one half comes before the first element of the other half. This
2202 * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a
2203 * copy of the array.
2204 *
2205 * @param a the array to be sorted
2206 * @param fromIndex the index of the first element to be sorted
2207 * @param toIndex the index of the last element to be sorted plus one
2208 * @throws ClassCastException if any two elements are not mutually
2209 * comparable
2210 * @throws NullPointerException if an element is null (since
2211 * null.compareTo cannot work)
2212 * @throws ArrayIndexOutOfBoundsException if fromIndex and toIndex
2213 * are not in range.
2214 * @throws IllegalArgumentException if fromIndex &gt; toIndex
2215 */
2216 public static void sort(Object[] a, int fromIndex, int toIndex)
2217 {
2218 sort(a, fromIndex, toIndex, null);
2219 }
2220
2221 /**
2222 * Sort an array of Objects according to a Comparator. The sort is
2223 * guaranteed to be stable, that is, equal elements will not be reordered.
2224 * The sort algorithm is a mergesort with the merge omitted if the last
2225 * element of one half comes before the first element of the other half. This
2226 * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a
2227 * copy of the array.
2228 *
2229 * @param a the array to be sorted
2230 * @param fromIndex the index of the first element to be sorted
2231 * @param toIndex the index of the last element to be sorted plus one
2232 * @param c a Comparator to use in sorting the array; or null to indicate
2233 * the elements' natural order
2234 * @throws ClassCastException if any two elements are not mutually
2235 * comparable by the Comparator provided
2236 * @throws ArrayIndexOutOfBoundsException if fromIndex and toIndex
2237 * are not in range.
2238 * @throws IllegalArgumentException if fromIndex &gt; toIndex
2239 * @throws NullPointerException if a null element is compared with natural
2240 * ordering (only possible when c is null)
2241 */
2242 public static void sort(Object[] a, int fromIndex, int toIndex, Comparator c)
2243 {
2244 if (fromIndex > toIndex)
2245 throw new IllegalArgumentException("fromIndex " + fromIndex
2246 + " > toIndex " + toIndex);
2247
2248 // In general, the code attempts to be simple rather than fast, the
2249 // idea being that a good optimising JIT will be able to optimise it
2250 // better than I can, and if I try it will make it more confusing for
2251 // the JIT. First presort the array in chunks of length 6 with insertion
2252 // sort. A mergesort would give too much overhead for this length.
2253 for (int chunk = fromIndex; chunk < toIndex; chunk += 6)
2254 {
2255 int end = Math.min(chunk + 6, toIndex);
2256 for (int i = chunk + 1; i < end; i++)
2257 {
2258 if (Collections.compare(a[i - 1], a[i], c) > 0)
2259 {
2260 // not already sorted
2261 int j = i;
2262 Object elem = a[j];
2263 do
2264 {
2265 a[j] = a[j - 1];
2266 j--;
2267 }
2268 while (j > chunk
2269 && Collections.compare(a[j - 1], elem, c) > 0);
2270 a[j] = elem;
2271 }
2272 }
2273 }
2274
2275 int len = toIndex - fromIndex;
2276 // If length is smaller or equal 6 we are done.
2277 if (len <= 6)
2278 return;
2279
2280 Object[] src = a;
2281 Object[] dest = new Object[len];
2282 Object[] t = null; // t is used for swapping src and dest
2283
2284 // The difference of the fromIndex of the src and dest array.
2285 int srcDestDiff = -fromIndex;
2286
2287 // The merges are done in this loop
2288 for (int size = 6; size < len; size <<= 1)
2289 {
2290 for (int start = fromIndex; start < toIndex; start += size << 1)
2291 {
2292 // mid is the start of the second sublist;
2293 // end the start of the next sublist (or end of array).
2294 int mid = start + size;
2295 int end = Math.min(toIndex, mid + size);
2296
2297 // The second list is empty or the elements are already in
2298 // order - no need to merge
2299 if (mid >= end
2300 || Collections.compare(src[mid - 1], src[mid], c) <= 0)
2301 {
2302 System.arraycopy(src, start,
2303 dest, start + srcDestDiff, end - start);
2304
2305 // The two halves just need swapping - no need to merge
2306 }
2307 else if (Collections.compare(src[start], src[end - 1], c) > 0)
2308 {
2309 System.arraycopy(src, start,
2310 dest, end - size + srcDestDiff, size);
2311 System.arraycopy(src, mid,
2312 dest, start + srcDestDiff, end - mid);
2313
2314 }
2315 else
2316 {
2317 // Declare a lot of variables to save repeating
2318 // calculations. Hopefully a decent JIT will put these
2319 // in registers and make this fast
2320 int p1 = start;
2321 int p2 = mid;
2322 int i = start + srcDestDiff;
2323
2324 // The main merge loop; terminates as soon as either
2325 // half is ended
2326 while (p1 < mid && p2 < end)
2327 {
2328 dest[i++] =
2329 src[(Collections.compare(src[p1], src[p2], c) <= 0
2330 ? p1++ : p2++)];
2331 }
2332
2333 // Finish up by copying the remainder of whichever half
2334 // wasn't finished.
2335 if (p1 < mid)
2336 System.arraycopy(src, p1, dest, i, mid - p1);
2337 else
2338 System.arraycopy(src, p2, dest, i, end - p2);
2339 }
2340 }
2341 // swap src and dest ready for the next merge
2342 t = src;
2343 src = dest;
2344 dest = t;
2345 fromIndex += srcDestDiff;
2346 toIndex += srcDestDiff;
2347 srcDestDiff = -srcDestDiff;
2348 }
2349
2350 // make sure the result ends up back in the right place. Note
2351 // that src and dest may have been swapped above, so src
2352 // contains the sorted array.
2353 if (src != a)
2354 {
2355 // Note that fromIndex == 0.
2356 System.arraycopy(src, 0, a, srcDestDiff, toIndex);
2357 }
2358 }
2359
2360 /**
2361 * Returns a list "view" of the specified array. This method is intended to
2362 * make it easy to use the Collections API with existing array-based APIs and
2363 * programs. Changes in the list or the array show up in both places. The
2364 * list does not support element addition or removal, but does permit
2365 * value modification. The returned list implements both Serializable and
2366 * RandomAccess.
2367 *
2368 * @param a the array to return a view of
2369 * @return a fixed-size list, changes to which "write through" to the array
2370 * @see Serializable
2371 * @see RandomAccess
2372 * @see Arrays.ArrayList
2373 */
2374 public static List asList(final Object[] a)
2375 {
2376 return new Arrays.ArrayList(a);
2377 }
2378
2379 /**
2380 * Inner class used by {@link #asList(Object[])} to provide a list interface
2381 * to an array. The name, though it clashes with java.util.ArrayList, is
2382 * Sun's choice for Serialization purposes. Element addition and removal
2383 * is prohibited, but values can be modified.
2384 *
2385 * @author Eric Blake <ebb9@email.byu.edu>
2386 * @status updated to 1.4
2387 */
2388 private static final class ArrayList extends AbstractList
2389 implements Serializable, RandomAccess
2390 {
2391 // We override the necessary methods, plus others which will be much
2392 // more efficient with direct iteration rather than relying on iterator().
2393
2394 /**
2395 * Compatible with JDK 1.4.
2396 */
2397 private static final long serialVersionUID = -2764017481108945198L;
2398
2399 /**
2400 * The array we are viewing.
2401 * @serial the array
2402 */
2403 private final Object[] a;
2404
2405 /**
2406 * Construct a list view of the array.
2407 * @param a the array to view
2408 * @throws NullPointerException if a is null
2409 */
2410 ArrayList(Object[] a)
2411 {
2412 // We have to explicitly check.
2413 if (a == null)
2414 throw new NullPointerException();
2415 this.a = a;
2416 }
2417
2418 public Object get(int index)
2419 {
2420 return a[index];
2421 }
2422
2423 public int size()
2424 {
2425 return a.length;
2426 }
2427
2428 public Object set(int index, Object element)
2429 {
2430 Object old = a[index];
2431 a[index] = element;
2432 return old;
2433 }
2434
2435 public boolean contains(Object o)
2436 {
2437 return lastIndexOf(o) >= 0;
2438 }
2439
2440 public int indexOf(Object o)
2441 {
2442 int size = a.length;
2443 for (int i = 0; i < size; i++)
2444 if (this.equals(o, a[i]))
2445 return i;
2446 return -1;
2447 }
2448
2449 public int lastIndexOf(Object o)
2450 {
2451 int i = a.length;
2452 while (--i >= 0)
2453 if (this.equals(o, a[i]))
2454 return i;
2455 return -1;
2456 }
2457
2458 public Object[] toArray()
2459 {
2460 return (Object[]) a.clone();
2461 }
2462
2463 public Object[] toArray(Object[] array)
2464 {
2465 int size = a.length;
2466 if (array.length < size)
2467 array = (Object[])
2468 Array.newInstance(array.getClass().getComponentType(), size);
2469 else if (array.length > size)
2470 array[size] = null;
2471
2472 System.arraycopy(a, 0, array, 0, size);
2473 return array;
2474 }
2475 }
2476}
Note: See TracBrowser for help on using the repository browser.