1. /*
  2. * @(#)Arrays.java 1.59 04/04/01
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util;
  8. import java.lang.reflect.*;
  9. /**
  10. * This class contains various methods for manipulating arrays (such as
  11. * sorting and searching). This class also contains a static factory
  12. * that allows arrays to be viewed as lists.
  13. *
  14. * <p>The methods in this class all throw a <tt>NullPointerException</tt> if
  15. * the specified array reference is null, except where noted.
  16. *
  17. * <p>The documentation for the methods contained in this class includes
  18. * briefs description of the <i>implementations</i>. Such descriptions should
  19. * be regarded as <i>implementation notes</i>, rather than parts of the
  20. * <i>specification</i>. Implementors should feel free to substitute other
  21. * algorithms, so long as the specification itself is adhered to. (For
  22. * example, the algorithm used by <tt>sort(Object[])</tt> does not have to be
  23. * a mergesort, but it does have to be <i>stable</i>.)
  24. *
  25. * <p>This class is a member of the
  26. * <a href="{@docRoot}/../guide/collections/index.html">
  27. * Java Collections Framework</a>.
  28. *
  29. * @author Josh Bloch
  30. * @author Neal Gafter
  31. * @version 1.59, 04/01/04
  32. * @see Comparable
  33. * @see Comparator
  34. * @since 1.2
  35. */
  36. public class Arrays {
  37. // Suppresses default constructor, ensuring non-instantiability.
  38. private Arrays() {
  39. }
  40. // Sorting
  41. /**
  42. * Sorts the specified array of longs into ascending numerical order.
  43. * The sorting algorithm is a tuned quicksort, adapted from Jon
  44. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  45. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  46. * 1993). This algorithm offers n*log(n) performance on many data sets
  47. * that cause other quicksorts to degrade to quadratic performance.
  48. *
  49. * @param a the array to be sorted.
  50. */
  51. public static void sort(long[] a) {
  52. sort1(a, 0, a.length);
  53. }
  54. /**
  55. * Sorts the specified range of the specified array of longs into
  56. * ascending numerical order. The range to be sorted extends from index
  57. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  58. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)
  59. *
  60. * <p>The sorting algorithm is a tuned quicksort, adapted from Jon
  61. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  62. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  63. * 1993). This algorithm offers n*log(n) performance on many data sets
  64. * that cause other quicksorts to degrade to quadratic performance.
  65. *
  66. * @param a the array to be sorted.
  67. * @param fromIndex the index of the first element (inclusive) to be
  68. * sorted.
  69. * @param toIndex the index of the last element (exclusive) to be sorted.
  70. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  71. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  72. * <tt>toIndex > a.length</tt>
  73. */
  74. public static void sort(long[] a, int fromIndex, int toIndex) {
  75. rangeCheck(a.length, fromIndex, toIndex);
  76. sort1(a, fromIndex, toIndex-fromIndex);
  77. }
  78. /**
  79. * Sorts the specified array of ints into ascending numerical order.
  80. * The sorting algorithm is a tuned quicksort, adapted from Jon
  81. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  82. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  83. * 1993). This algorithm offers n*log(n) performance on many data sets
  84. * that cause other quicksorts to degrade to quadratic performance.
  85. *
  86. * @param a the array to be sorted.
  87. */
  88. public static void sort(int[] a) {
  89. sort1(a, 0, a.length);
  90. }
  91. /**
  92. * Sorts the specified range of the specified array of ints into
  93. * ascending numerical order. The range to be sorted extends from index
  94. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  95. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
  96. *
  97. * The sorting algorithm is a tuned quicksort, adapted from Jon
  98. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  99. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  100. * 1993). This algorithm offers n*log(n) performance on many data sets
  101. * that cause other quicksorts to degrade to quadratic performance.
  102. *
  103. * @param a the array to be sorted.
  104. * @param fromIndex the index of the first element (inclusive) to be
  105. * sorted.
  106. * @param toIndex the index of the last element (exclusive) to be sorted.
  107. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  108. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  109. * <tt>toIndex > a.length</tt>
  110. */
  111. public static void sort(int[] a, int fromIndex, int toIndex) {
  112. rangeCheck(a.length, fromIndex, toIndex);
  113. sort1(a, fromIndex, toIndex-fromIndex);
  114. }
  115. /**
  116. * Sorts the specified array of shorts into ascending numerical order.
  117. * The sorting algorithm is a tuned quicksort, adapted from Jon
  118. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  119. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  120. * 1993). This algorithm offers n*log(n) performance on many data sets
  121. * that cause other quicksorts to degrade to quadratic performance.
  122. *
  123. * @param a the array to be sorted.
  124. */
  125. public static void sort(short[] a) {
  126. sort1(a, 0, a.length);
  127. }
  128. /**
  129. * Sorts the specified range of the specified array of shorts into
  130. * ascending numerical order. The range to be sorted extends from index
  131. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  132. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
  133. *
  134. * The sorting algorithm is a tuned quicksort, adapted from Jon
  135. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  136. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  137. * 1993). This algorithm offers n*log(n) performance on many data sets
  138. * that cause other quicksorts to degrade to quadratic performance.
  139. *
  140. * @param a the array to be sorted.
  141. * @param fromIndex the index of the first element (inclusive) to be
  142. * sorted.
  143. * @param toIndex the index of the last element (exclusive) to be sorted.
  144. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  145. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  146. * <tt>toIndex > a.length</tt>
  147. */
  148. public static void sort(short[] a, int fromIndex, int toIndex) {
  149. rangeCheck(a.length, fromIndex, toIndex);
  150. sort1(a, fromIndex, toIndex-fromIndex);
  151. }
  152. /**
  153. * Sorts the specified array of chars into ascending numerical order.
  154. * The sorting algorithm is a tuned quicksort, adapted from Jon
  155. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  156. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  157. * 1993). This algorithm offers n*log(n) performance on many data sets
  158. * that cause other quicksorts to degrade to quadratic performance.
  159. *
  160. * @param a the array to be sorted.
  161. */
  162. public static void sort(char[] a) {
  163. sort1(a, 0, a.length);
  164. }
  165. /**
  166. * Sorts the specified range of the specified array of chars into
  167. * ascending numerical order. The range to be sorted extends from index
  168. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  169. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
  170. *
  171. * The sorting algorithm is a tuned quicksort, adapted from Jon
  172. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  173. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  174. * 1993). This algorithm offers n*log(n) performance on many data sets
  175. * that cause other quicksorts to degrade to quadratic performance.
  176. *
  177. * @param a the array to be sorted.
  178. * @param fromIndex the index of the first element (inclusive) to be
  179. * sorted.
  180. * @param toIndex the index of the last element (exclusive) to be sorted.
  181. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  182. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  183. * <tt>toIndex > a.length</tt>
  184. */
  185. public static void sort(char[] a, int fromIndex, int toIndex) {
  186. rangeCheck(a.length, fromIndex, toIndex);
  187. sort1(a, fromIndex, toIndex-fromIndex);
  188. }
  189. /**
  190. * Sorts the specified array of bytes into ascending numerical order.
  191. * The sorting algorithm is a tuned quicksort, adapted from Jon
  192. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  193. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  194. * 1993). This algorithm offers n*log(n) performance on many data sets
  195. * that cause other quicksorts to degrade to quadratic performance.
  196. *
  197. * @param a the array to be sorted.
  198. */
  199. public static void sort(byte[] a) {
  200. sort1(a, 0, a.length);
  201. }
  202. /**
  203. * Sorts the specified range of the specified array of bytes into
  204. * ascending numerical order. The range to be sorted extends from index
  205. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  206. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
  207. *
  208. * The sorting algorithm is a tuned quicksort, adapted from Jon
  209. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  210. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  211. * 1993). This algorithm offers n*log(n) performance on many data sets
  212. * that cause other quicksorts to degrade to quadratic performance.
  213. *
  214. * @param a the array to be sorted.
  215. * @param fromIndex the index of the first element (inclusive) to be
  216. * sorted.
  217. * @param toIndex the index of the last element (exclusive) to be sorted.
  218. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  219. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  220. * <tt>toIndex > a.length</tt>
  221. */
  222. public static void sort(byte[] a, int fromIndex, int toIndex) {
  223. rangeCheck(a.length, fromIndex, toIndex);
  224. sort1(a, fromIndex, toIndex-fromIndex);
  225. }
  226. /**
  227. * Sorts the specified array of doubles into ascending numerical order.
  228. * <p>
  229. * The <code><</code> relation does not provide a total order on
  230. * all floating-point values; although they are distinct numbers
  231. * <code>-0.0 == 0.0</code> is <code>true</code> and a NaN value
  232. * compares neither less than, greater than, nor equal to any
  233. * floating-point value, even itself. To allow the sort to
  234. * proceed, instead of using the <code><</code> relation to
  235. * determine ascending numerical order, this method uses the total
  236. * order imposed by {@link Double#compareTo}. This ordering
  237. * differs from the <code><</code> relation in that
  238. * <code>-0.0</code> is treated as less than <code>0.0</code> and
  239. * NaN is considered greater than any other floating-point value.
  240. * For the purposes of sorting, all NaN values are considered
  241. * equivalent and equal.
  242. * <p>
  243. * The sorting algorithm is a tuned quicksort, adapted from Jon
  244. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  245. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  246. * 1993). This algorithm offers n*log(n) performance on many data sets
  247. * that cause other quicksorts to degrade to quadratic performance.
  248. *
  249. * @param a the array to be sorted.
  250. */
  251. public static void sort(double[] a) {
  252. sort2(a, 0, a.length);
  253. }
  254. /**
  255. * Sorts the specified range of the specified array of doubles into
  256. * ascending numerical order. The range to be sorted extends from index
  257. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  258. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)
  259. * <p>
  260. * The <code><</code> relation does not provide a total order on
  261. * all floating-point values; although they are distinct numbers
  262. * <code>-0.0 == 0.0</code> is <code>true</code> and a NaN value
  263. * compares neither less than, greater than, nor equal to any
  264. * floating-point value, even itself. To allow the sort to
  265. * proceed, instead of using the <code><</code> relation to
  266. * determine ascending numerical order, this method uses the total
  267. * order imposed by {@link Double#compareTo}. This ordering
  268. * differs from the <code><</code> relation in that
  269. * <code>-0.0</code> is treated as less than <code>0.0</code> and
  270. * NaN is considered greater than any other floating-point value.
  271. * For the purposes of sorting, all NaN values are considered
  272. * equivalent and equal.
  273. * <p>
  274. * The sorting algorithm is a tuned quicksort, adapted from Jon
  275. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  276. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  277. * 1993). This algorithm offers n*log(n) performance on many data sets
  278. * that cause other quicksorts to degrade to quadratic performance.
  279. *
  280. * @param a the array to be sorted.
  281. * @param fromIndex the index of the first element (inclusive) to be
  282. * sorted.
  283. * @param toIndex the index of the last element (exclusive) to be sorted.
  284. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  285. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  286. * <tt>toIndex > a.length</tt>
  287. */
  288. public static void sort(double[] a, int fromIndex, int toIndex) {
  289. rangeCheck(a.length, fromIndex, toIndex);
  290. sort2(a, fromIndex, toIndex);
  291. }
  292. /**
  293. * Sorts the specified array of floats into ascending numerical order.
  294. * <p>
  295. * The <code><</code> relation does not provide a total order on
  296. * all floating-point values; although they are distinct numbers
  297. * <code>-0.0f == 0.0f</code> is <code>true</code> and a NaN value
  298. * compares neither less than, greater than, nor equal to any
  299. * floating-point value, even itself. To allow the sort to
  300. * proceed, instead of using the <code><</code> relation to
  301. * determine ascending numerical order, this method uses the total
  302. * order imposed by {@link Float#compareTo}. This ordering
  303. * differs from the <code><</code> relation in that
  304. * <code>-0.0f</code> is treated as less than <code>0.0f</code> and
  305. * NaN is considered greater than any other floating-point value.
  306. * For the purposes of sorting, all NaN values are considered
  307. * equivalent and equal.
  308. * <p>
  309. * The sorting algorithm is a tuned quicksort, adapted from Jon
  310. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  311. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  312. * 1993). This algorithm offers n*log(n) performance on many data sets
  313. * that cause other quicksorts to degrade to quadratic performance.
  314. *
  315. * @param a the array to be sorted.
  316. */
  317. public static void sort(float[] a) {
  318. sort2(a, 0, a.length);
  319. }
  320. /**
  321. * Sorts the specified range of the specified array of floats into
  322. * ascending numerical order. The range to be sorted extends from index
  323. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  324. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)
  325. * <p>
  326. * The <code><</code> relation does not provide a total order on
  327. * all floating-point values; although they are distinct numbers
  328. * <code>-0.0f == 0.0f</code> is <code>true</code> and a NaN value
  329. * compares neither less than, greater than, nor equal to any
  330. * floating-point value, even itself. To allow the sort to
  331. * proceed, instead of using the <code><</code> relation to
  332. * determine ascending numerical order, this method uses the total
  333. * order imposed by {@link Float#compareTo}. This ordering
  334. * differs from the <code><</code> relation in that
  335. * <code>-0.0f</code> is treated as less than <code>0.0f</code> and
  336. * NaN is considered greater than any other floating-point value.
  337. * For the purposes of sorting, all NaN values are considered
  338. * equivalent and equal.
  339. * <p>
  340. * The sorting algorithm is a tuned quicksort, adapted from Jon
  341. * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
  342. * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
  343. * 1993). This algorithm offers n*log(n) performance on many data sets
  344. * that cause other quicksorts to degrade to quadratic performance.
  345. *
  346. * @param a the array to be sorted.
  347. * @param fromIndex the index of the first element (inclusive) to be
  348. * sorted.
  349. * @param toIndex the index of the last element (exclusive) to be sorted.
  350. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  351. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  352. * <tt>toIndex > a.length</tt>
  353. */
  354. public static void sort(float[] a, int fromIndex, int toIndex) {
  355. rangeCheck(a.length, fromIndex, toIndex);
  356. sort2(a, fromIndex, toIndex);
  357. }
  358. private static void sort2(double a[], int fromIndex, int toIndex) {
  359. final long NEG_ZERO_BITS = Double.doubleToLongBits(-0.0d);
  360. /*
  361. * The sort is done in three phases to avoid the expense of using
  362. * NaN and -0.0 aware comparisons during the main sort.
  363. */
  364. /*
  365. * Preprocessing phase: Move any NaN's to end of array, count the
  366. * number of -0.0's, and turn them into 0.0's.
  367. */
  368. int numNegZeros = 0;
  369. int i = fromIndex, n = toIndex;
  370. while(i < n) {
  371. if (a[i] != a[i]) {
  372. double swap = a[i];
  373. a[i] = a[--n];
  374. a[n] = swap;
  375. } else {
  376. if (a[i]==0 && Double.doubleToLongBits(a[i])==NEG_ZERO_BITS) {
  377. a[i] = 0.0d;
  378. numNegZeros++;
  379. }
  380. i++;
  381. }
  382. }
  383. // Main sort phase: quicksort everything but the NaN's
  384. sort1(a, fromIndex, n-fromIndex);
  385. // Postprocessing phase: change 0.0's to -0.0's as required
  386. if (numNegZeros != 0) {
  387. int j = binarySearch(a, 0.0d, fromIndex, n-1); // posn of ANY zero
  388. do {
  389. j--;
  390. } while (j>=0 && a[j]==0.0d);
  391. // j is now one less than the index of the FIRST zero
  392. for (int k=0; k<numNegZeros; k++)
  393. a[++j] = -0.0d;
  394. }
  395. }
  396. private static void sort2(float a[], int fromIndex, int toIndex) {
  397. final int NEG_ZERO_BITS = Float.floatToIntBits(-0.0f);
  398. /*
  399. * The sort is done in three phases to avoid the expense of using
  400. * NaN and -0.0 aware comparisons during the main sort.
  401. */
  402. /*
  403. * Preprocessing phase: Move any NaN's to end of array, count the
  404. * number of -0.0's, and turn them into 0.0's.
  405. */
  406. int numNegZeros = 0;
  407. int i = fromIndex, n = toIndex;
  408. while(i < n) {
  409. if (a[i] != a[i]) {
  410. float swap = a[i];
  411. a[i] = a[--n];
  412. a[n] = swap;
  413. } else {
  414. if (a[i]==0 && Float.floatToIntBits(a[i])==NEG_ZERO_BITS) {
  415. a[i] = 0.0f;
  416. numNegZeros++;
  417. }
  418. i++;
  419. }
  420. }
  421. // Main sort phase: quicksort everything but the NaN's
  422. sort1(a, fromIndex, n-fromIndex);
  423. // Postprocessing phase: change 0.0's to -0.0's as required
  424. if (numNegZeros != 0) {
  425. int j = binarySearch(a, 0.0f, fromIndex, n-1); // posn of ANY zero
  426. do {
  427. j--;
  428. } while (j>=0 && a[j]==0.0f);
  429. // j is now one less than the index of the FIRST zero
  430. for (int k=0; k<numNegZeros; k++)
  431. a[++j] = -0.0f;
  432. }
  433. }
  434. /*
  435. * The code for each of the seven primitive types is largely identical.
  436. * C'est la vie.
  437. */
  438. /**
  439. * Sorts the specified sub-array of longs into ascending order.
  440. */
  441. private static void sort1(long x[], int off, int len) {
  442. // Insertion sort on smallest arrays
  443. if (len < 7) {
  444. for (int i=off; i<len+off; i++)
  445. for (int j=i; j>off && x[j-1]>x[j]; j--)
  446. swap(x, j, j-1);
  447. return;
  448. }
  449. // Choose a partition element, v
  450. int m = off + (len >> 1); // Small arrays, middle element
  451. if (len > 7) {
  452. int l = off;
  453. int n = off + len - 1;
  454. if (len > 40) { // Big arrays, pseudomedian of 9
  455. int s = len8;
  456. l = med3(x, l, l+s, l+2*s);
  457. m = med3(x, m-s, m, m+s);
  458. n = med3(x, n-2*s, n-s, n);
  459. }
  460. m = med3(x, l, m, n); // Mid-size, med of 3
  461. }
  462. long v = x[m];
  463. // Establish Invariant: v* (<v)* (>v)* v*
  464. int a = off, b = a, c = off + len - 1, d = c;
  465. while(true) {
  466. while (b <= c && x[b] <= v) {
  467. if (x[b] == v)
  468. swap(x, a++, b);
  469. b++;
  470. }
  471. while (c >= b && x[c] >= v) {
  472. if (x[c] == v)
  473. swap(x, c, d--);
  474. c--;
  475. }
  476. if (b > c)
  477. break;
  478. swap(x, b++, c--);
  479. }
  480. // Swap partition elements back to middle
  481. int s, n = off + len;
  482. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  483. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  484. // Recursively sort non-partition-elements
  485. if ((s = b-a) > 1)
  486. sort1(x, off, s);
  487. if ((s = d-c) > 1)
  488. sort1(x, n-s, s);
  489. }
  490. /**
  491. * Swaps x[a] with x[b].
  492. */
  493. private static void swap(long x[], int a, int b) {
  494. long t = x[a];
  495. x[a] = x[b];
  496. x[b] = t;
  497. }
  498. /**
  499. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  500. */
  501. private static void vecswap(long x[], int a, int b, int n) {
  502. for (int i=0; i<n; i++, a++, b++)
  503. swap(x, a, b);
  504. }
  505. /**
  506. * Returns the index of the median of the three indexed longs.
  507. */
  508. private static int med3(long x[], int a, int b, int c) {
  509. return (x[a] < x[b] ?
  510. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  511. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  512. }
  513. /**
  514. * Sorts the specified sub-array of integers into ascending order.
  515. */
  516. private static void sort1(int x[], int off, int len) {
  517. // Insertion sort on smallest arrays
  518. if (len < 7) {
  519. for (int i=off; i<len+off; i++)
  520. for (int j=i; j>off && x[j-1]>x[j]; j--)
  521. swap(x, j, j-1);
  522. return;
  523. }
  524. // Choose a partition element, v
  525. int m = off + (len >> 1); // Small arrays, middle element
  526. if (len > 7) {
  527. int l = off;
  528. int n = off + len - 1;
  529. if (len > 40) { // Big arrays, pseudomedian of 9
  530. int s = len8;
  531. l = med3(x, l, l+s, l+2*s);
  532. m = med3(x, m-s, m, m+s);
  533. n = med3(x, n-2*s, n-s, n);
  534. }
  535. m = med3(x, l, m, n); // Mid-size, med of 3
  536. }
  537. int v = x[m];
  538. // Establish Invariant: v* (<v)* (>v)* v*
  539. int a = off, b = a, c = off + len - 1, d = c;
  540. while(true) {
  541. while (b <= c && x[b] <= v) {
  542. if (x[b] == v)
  543. swap(x, a++, b);
  544. b++;
  545. }
  546. while (c >= b && x[c] >= v) {
  547. if (x[c] == v)
  548. swap(x, c, d--);
  549. c--;
  550. }
  551. if (b > c)
  552. break;
  553. swap(x, b++, c--);
  554. }
  555. // Swap partition elements back to middle
  556. int s, n = off + len;
  557. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  558. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  559. // Recursively sort non-partition-elements
  560. if ((s = b-a) > 1)
  561. sort1(x, off, s);
  562. if ((s = d-c) > 1)
  563. sort1(x, n-s, s);
  564. }
  565. /**
  566. * Swaps x[a] with x[b].
  567. */
  568. private static void swap(int x[], int a, int b) {
  569. int t = x[a];
  570. x[a] = x[b];
  571. x[b] = t;
  572. }
  573. /**
  574. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  575. */
  576. private static void vecswap(int x[], int a, int b, int n) {
  577. for (int i=0; i<n; i++, a++, b++)
  578. swap(x, a, b);
  579. }
  580. /**
  581. * Returns the index of the median of the three indexed integers.
  582. */
  583. private static int med3(int x[], int a, int b, int c) {
  584. return (x[a] < x[b] ?
  585. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  586. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  587. }
  588. /**
  589. * Sorts the specified sub-array of shorts into ascending order.
  590. */
  591. private static void sort1(short x[], int off, int len) {
  592. // Insertion sort on smallest arrays
  593. if (len < 7) {
  594. for (int i=off; i<len+off; i++)
  595. for (int j=i; j>off && x[j-1]>x[j]; j--)
  596. swap(x, j, j-1);
  597. return;
  598. }
  599. // Choose a partition element, v
  600. int m = off + (len >> 1); // Small arrays, middle element
  601. if (len > 7) {
  602. int l = off;
  603. int n = off + len - 1;
  604. if (len > 40) { // Big arrays, pseudomedian of 9
  605. int s = len8;
  606. l = med3(x, l, l+s, l+2*s);
  607. m = med3(x, m-s, m, m+s);
  608. n = med3(x, n-2*s, n-s, n);
  609. }
  610. m = med3(x, l, m, n); // Mid-size, med of 3
  611. }
  612. short v = x[m];
  613. // Establish Invariant: v* (<v)* (>v)* v*
  614. int a = off, b = a, c = off + len - 1, d = c;
  615. while(true) {
  616. while (b <= c && x[b] <= v) {
  617. if (x[b] == v)
  618. swap(x, a++, b);
  619. b++;
  620. }
  621. while (c >= b && x[c] >= v) {
  622. if (x[c] == v)
  623. swap(x, c, d--);
  624. c--;
  625. }
  626. if (b > c)
  627. break;
  628. swap(x, b++, c--);
  629. }
  630. // Swap partition elements back to middle
  631. int s, n = off + len;
  632. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  633. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  634. // Recursively sort non-partition-elements
  635. if ((s = b-a) > 1)
  636. sort1(x, off, s);
  637. if ((s = d-c) > 1)
  638. sort1(x, n-s, s);
  639. }
  640. /**
  641. * Swaps x[a] with x[b].
  642. */
  643. private static void swap(short x[], int a, int b) {
  644. short t = x[a];
  645. x[a] = x[b];
  646. x[b] = t;
  647. }
  648. /**
  649. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  650. */
  651. private static void vecswap(short x[], int a, int b, int n) {
  652. for (int i=0; i<n; i++, a++, b++)
  653. swap(x, a, b);
  654. }
  655. /**
  656. * Returns the index of the median of the three indexed shorts.
  657. */
  658. private static int med3(short x[], int a, int b, int c) {
  659. return (x[a] < x[b] ?
  660. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  661. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  662. }
  663. /**
  664. * Sorts the specified sub-array of chars into ascending order.
  665. */
  666. private static void sort1(char x[], int off, int len) {
  667. // Insertion sort on smallest arrays
  668. if (len < 7) {
  669. for (int i=off; i<len+off; i++)
  670. for (int j=i; j>off && x[j-1]>x[j]; j--)
  671. swap(x, j, j-1);
  672. return;
  673. }
  674. // Choose a partition element, v
  675. int m = off + (len >> 1); // Small arrays, middle element
  676. if (len > 7) {
  677. int l = off;
  678. int n = off + len - 1;
  679. if (len > 40) { // Big arrays, pseudomedian of 9
  680. int s = len8;
  681. l = med3(x, l, l+s, l+2*s);
  682. m = med3(x, m-s, m, m+s);
  683. n = med3(x, n-2*s, n-s, n);
  684. }
  685. m = med3(x, l, m, n); // Mid-size, med of 3
  686. }
  687. char v = x[m];
  688. // Establish Invariant: v* (<v)* (>v)* v*
  689. int a = off, b = a, c = off + len - 1, d = c;
  690. while(true) {
  691. while (b <= c && x[b] <= v) {
  692. if (x[b] == v)
  693. swap(x, a++, b);
  694. b++;
  695. }
  696. while (c >= b && x[c] >= v) {
  697. if (x[c] == v)
  698. swap(x, c, d--);
  699. c--;
  700. }
  701. if (b > c)
  702. break;
  703. swap(x, b++, c--);
  704. }
  705. // Swap partition elements back to middle
  706. int s, n = off + len;
  707. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  708. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  709. // Recursively sort non-partition-elements
  710. if ((s = b-a) > 1)
  711. sort1(x, off, s);
  712. if ((s = d-c) > 1)
  713. sort1(x, n-s, s);
  714. }
  715. /**
  716. * Swaps x[a] with x[b].
  717. */
  718. private static void swap(char x[], int a, int b) {
  719. char t = x[a];
  720. x[a] = x[b];
  721. x[b] = t;
  722. }
  723. /**
  724. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  725. */
  726. private static void vecswap(char x[], int a, int b, int n) {
  727. for (int i=0; i<n; i++, a++, b++)
  728. swap(x, a, b);
  729. }
  730. /**
  731. * Returns the index of the median of the three indexed chars.
  732. */
  733. private static int med3(char x[], int a, int b, int c) {
  734. return (x[a] < x[b] ?
  735. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  736. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  737. }
  738. /**
  739. * Sorts the specified sub-array of bytes into ascending order.
  740. */
  741. private static void sort1(byte x[], int off, int len) {
  742. // Insertion sort on smallest arrays
  743. if (len < 7) {
  744. for (int i=off; i<len+off; i++)
  745. for (int j=i; j>off && x[j-1]>x[j]; j--)
  746. swap(x, j, j-1);
  747. return;
  748. }
  749. // Choose a partition element, v
  750. int m = off + (len >> 1); // Small arrays, middle element
  751. if (len > 7) {
  752. int l = off;
  753. int n = off + len - 1;
  754. if (len > 40) { // Big arrays, pseudomedian of 9
  755. int s = len8;
  756. l = med3(x, l, l+s, l+2*s);
  757. m = med3(x, m-s, m, m+s);
  758. n = med3(x, n-2*s, n-s, n);
  759. }
  760. m = med3(x, l, m, n); // Mid-size, med of 3
  761. }
  762. byte v = x[m];
  763. // Establish Invariant: v* (<v)* (>v)* v*
  764. int a = off, b = a, c = off + len - 1, d = c;
  765. while(true) {
  766. while (b <= c && x[b] <= v) {
  767. if (x[b] == v)
  768. swap(x, a++, b);
  769. b++;
  770. }
  771. while (c >= b && x[c] >= v) {
  772. if (x[c] == v)
  773. swap(x, c, d--);
  774. c--;
  775. }
  776. if (b > c)
  777. break;
  778. swap(x, b++, c--);
  779. }
  780. // Swap partition elements back to middle
  781. int s, n = off + len;
  782. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  783. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  784. // Recursively sort non-partition-elements
  785. if ((s = b-a) > 1)
  786. sort1(x, off, s);
  787. if ((s = d-c) > 1)
  788. sort1(x, n-s, s);
  789. }
  790. /**
  791. * Swaps x[a] with x[b].
  792. */
  793. private static void swap(byte x[], int a, int b) {
  794. byte t = x[a];
  795. x[a] = x[b];
  796. x[b] = t;
  797. }
  798. /**
  799. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  800. */
  801. private static void vecswap(byte x[], int a, int b, int n) {
  802. for (int i=0; i<n; i++, a++, b++)
  803. swap(x, a, b);
  804. }
  805. /**
  806. * Returns the index of the median of the three indexed bytes.
  807. */
  808. private static int med3(byte x[], int a, int b, int c) {
  809. return (x[a] < x[b] ?
  810. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  811. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  812. }
  813. /**
  814. * Sorts the specified sub-array of doubles into ascending order.
  815. */
  816. private static void sort1(double x[], int off, int len) {
  817. // Insertion sort on smallest arrays
  818. if (len < 7) {
  819. for (int i=off; i<len+off; i++)
  820. for (int j=i; j>off && x[j-1]>x[j]; j--)
  821. swap(x, j, j-1);
  822. return;
  823. }
  824. // Choose a partition element, v
  825. int m = off + (len >> 1); // Small arrays, middle element
  826. if (len > 7) {
  827. int l = off;
  828. int n = off + len - 1;
  829. if (len > 40) { // Big arrays, pseudomedian of 9
  830. int s = len8;
  831. l = med3(x, l, l+s, l+2*s);
  832. m = med3(x, m-s, m, m+s);
  833. n = med3(x, n-2*s, n-s, n);
  834. }
  835. m = med3(x, l, m, n); // Mid-size, med of 3
  836. }
  837. double v = x[m];
  838. // Establish Invariant: v* (<v)* (>v)* v*
  839. int a = off, b = a, c = off + len - 1, d = c;
  840. while(true) {
  841. while (b <= c && x[b] <= v) {
  842. if (x[b] == v)
  843. swap(x, a++, b);
  844. b++;
  845. }
  846. while (c >= b && x[c] >= v) {
  847. if (x[c] == v)
  848. swap(x, c, d--);
  849. c--;
  850. }
  851. if (b > c)
  852. break;
  853. swap(x, b++, c--);
  854. }
  855. // Swap partition elements back to middle
  856. int s, n = off + len;
  857. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  858. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  859. // Recursively sort non-partition-elements
  860. if ((s = b-a) > 1)
  861. sort1(x, off, s);
  862. if ((s = d-c) > 1)
  863. sort1(x, n-s, s);
  864. }
  865. /**
  866. * Swaps x[a] with x[b].
  867. */
  868. private static void swap(double x[], int a, int b) {
  869. double t = x[a];
  870. x[a] = x[b];
  871. x[b] = t;
  872. }
  873. /**
  874. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  875. */
  876. private static void vecswap(double x[], int a, int b, int n) {
  877. for (int i=0; i<n; i++, a++, b++)
  878. swap(x, a, b);
  879. }
  880. /**
  881. * Returns the index of the median of the three indexed doubles.
  882. */
  883. private static int med3(double x[], int a, int b, int c) {
  884. return (x[a] < x[b] ?
  885. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  886. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  887. }
  888. /**
  889. * Sorts the specified sub-array of floats into ascending order.
  890. */
  891. private static void sort1(float x[], int off, int len) {
  892. // Insertion sort on smallest arrays
  893. if (len < 7) {
  894. for (int i=off; i<len+off; i++)
  895. for (int j=i; j>off && x[j-1]>x[j]; j--)
  896. swap(x, j, j-1);
  897. return;
  898. }
  899. // Choose a partition element, v
  900. int m = off + (len >> 1); // Small arrays, middle element
  901. if (len > 7) {
  902. int l = off;
  903. int n = off + len - 1;
  904. if (len > 40) { // Big arrays, pseudomedian of 9
  905. int s = len8;
  906. l = med3(x, l, l+s, l+2*s);
  907. m = med3(x, m-s, m, m+s);
  908. n = med3(x, n-2*s, n-s, n);
  909. }
  910. m = med3(x, l, m, n); // Mid-size, med of 3
  911. }
  912. float v = x[m];
  913. // Establish Invariant: v* (<v)* (>v)* v*
  914. int a = off, b = a, c = off + len - 1, d = c;
  915. while(true) {
  916. while (b <= c && x[b] <= v) {
  917. if (x[b] == v)
  918. swap(x, a++, b);
  919. b++;
  920. }
  921. while (c >= b && x[c] >= v) {
  922. if (x[c] == v)
  923. swap(x, c, d--);
  924. c--;
  925. }
  926. if (b > c)
  927. break;
  928. swap(x, b++, c--);
  929. }
  930. // Swap partition elements back to middle
  931. int s, n = off + len;
  932. s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
  933. s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
  934. // Recursively sort non-partition-elements
  935. if ((s = b-a) > 1)
  936. sort1(x, off, s);
  937. if ((s = d-c) > 1)
  938. sort1(x, n-s, s);
  939. }
  940. /**
  941. * Swaps x[a] with x[b].
  942. */
  943. private static void swap(float x[], int a, int b) {
  944. float t = x[a];
  945. x[a] = x[b];
  946. x[b] = t;
  947. }
  948. /**
  949. * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
  950. */
  951. private static void vecswap(float x[], int a, int b, int n) {
  952. for (int i=0; i<n; i++, a++, b++)
  953. swap(x, a, b);
  954. }
  955. /**
  956. * Returns the index of the median of the three indexed floats.
  957. */
  958. private static int med3(float x[], int a, int b, int c) {
  959. return (x[a] < x[b] ?
  960. (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
  961. (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
  962. }
  963. /**
  964. * Sorts the specified array of objects into ascending order, according to
  965. * the <i>natural ordering</i> of its elements. All elements in the array
  966. * must implement the <tt>Comparable</tt> interface. Furthermore, all
  967. * elements in the array must be <i>mutually comparable</i> (that is,
  968. * <tt>e1.compareTo(e2)</tt> must not throw a <tt>ClassCastException</tt>
  969. * for any elements <tt>e1</tt> and <tt>e2</tt> in the array).<p>
  970. *
  971. * This sort is guaranteed to be <i>stable</i>: equal elements will
  972. * not be reordered as a result of the sort.<p>
  973. *
  974. * The sorting algorithm is a modified mergesort (in which the merge is
  975. * omitted if the highest element in the low sublist is less than the
  976. * lowest element in the high sublist). This algorithm offers guaranteed
  977. * n*log(n) performance.
  978. *
  979. * @param a the array to be sorted.
  980. * @throws ClassCastException if the array contains elements that are not
  981. * <i>mutually comparable</i> (for example, strings and integers).
  982. * @see Comparable
  983. */
  984. public static void sort(Object[] a) {
  985. Object[] aux = (Object[])a.clone();
  986. mergeSort(aux, a, 0, a.length, 0);
  987. }
  988. /**
  989. * Sorts the specified range of the specified array of objects into
  990. * ascending order, according to the <i>natural ordering</i> of its
  991. * elements. The range to be sorted extends from index
  992. * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
  993. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.) All
  994. * elements in this range must implement the <tt>Comparable</tt>
  995. * interface. Furthermore, all elements in this range must be <i>mutually
  996. * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  997. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  998. * <tt>e2</tt> in the array).<p>
  999. *
  1000. * This sort is guaranteed to be <i>stable</i>: equal elements will
  1001. * not be reordered as a result of the sort.<p>
  1002. *
  1003. * The sorting algorithm is a modified mergesort (in which the merge is
  1004. * omitted if the highest element in the low sublist is less than the
  1005. * lowest element in the high sublist). This algorithm offers guaranteed
  1006. * n*log(n) performance.
  1007. *
  1008. * @param a the array to be sorted.
  1009. * @param fromIndex the index of the first element (inclusive) to be
  1010. * sorted.
  1011. * @param toIndex the index of the last element (exclusive) to be sorted.
  1012. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1013. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1014. * <tt>toIndex > a.length</tt>
  1015. * @throws ClassCastException if the array contains elements that are
  1016. * not <i>mutually comparable</i> (for example, strings and
  1017. * integers).
  1018. * @see Comparable
  1019. */
  1020. public static void sort(Object[] a, int fromIndex, int toIndex) {
  1021. rangeCheck(a.length, fromIndex, toIndex);
  1022. Object[] aux = cloneSubarray(a, fromIndex, toIndex);
  1023. mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
  1024. }
  1025. /**
  1026. * Tuning parameter: list size at or below which insertion sort will be
  1027. * used in preference to mergesort or quicksort.
  1028. */
  1029. private static final int INSERTIONSORT_THRESHOLD = 7;
  1030. /**
  1031. * Clones an array within the specified bounds.
  1032. * This method assumes that a is an array.
  1033. */
  1034. private static <T> T[] cloneSubarray(T[] a, int from, int to) {
  1035. int n = to - from;
  1036. T[] result = (T[])Array.newInstance(a.getClass().getComponentType(), n);
  1037. System.arraycopy(a, from, result, 0, n);
  1038. return result;
  1039. }
  1040. /**
  1041. * Src is the source array that starts at index 0
  1042. * Dest is the (possibly larger) array destination with a possible offset
  1043. * low is the index in dest to start sorting
  1044. * high is the end index in dest to end sorting
  1045. * off is the offset to generate corresponding low, high in src
  1046. */
  1047. private static void mergeSort(Object[] src,
  1048. Object[] dest,
  1049. int low,
  1050. int high,
  1051. int off) {
  1052. int length = high - low;
  1053. // Insertion sort on smallest arrays
  1054. if (length < INSERTIONSORT_THRESHOLD) {
  1055. for (int i=low; i<high; i++)
  1056. for (int j=i; j>low &&
  1057. ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
  1058. swap(dest, j, j-1);
  1059. return;
  1060. }
  1061. // Recursively sort halves of dest into src
  1062. int destLow = low;
  1063. int destHigh = high;
  1064. low += off;
  1065. high += off;
  1066. int mid = (low + high) >> 1;
  1067. mergeSort(dest, src, low, mid, -off);
  1068. mergeSort(dest, src, mid, high, -off);
  1069. // If list is already sorted, just copy from src to dest. This is an
  1070. // optimization that results in faster sorts for nearly ordered lists.
  1071. if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
  1072. System.arraycopy(src, low, dest, destLow, length);
  1073. return;
  1074. }
  1075. // Merge sorted halves (now in src) into dest
  1076. for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
  1077. if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
  1078. dest[i] = src[p++];
  1079. else
  1080. dest[i] = src[q++];
  1081. }
  1082. }
  1083. /**
  1084. * Swaps x[a] with x[b].
  1085. */
  1086. private static void swap(Object[] x, int a, int b) {
  1087. Object t = x[a];
  1088. x[a] = x[b];
  1089. x[b] = t;
  1090. }
  1091. /**
  1092. * Sorts the specified array of objects according to the order induced by
  1093. * the specified comparator. All elements in the array must be
  1094. * <i>mutually comparable</i> by the specified comparator (that is,
  1095. * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt>
  1096. * for any elements <tt>e1</tt> and <tt>e2</tt> in the array).<p>
  1097. *
  1098. * This sort is guaranteed to be <i>stable</i>: equal elements will
  1099. * not be reordered as a result of the sort.<p>
  1100. *
  1101. * The sorting algorithm is a modified mergesort (in which the merge is
  1102. * omitted if the highest element in the low sublist is less than the
  1103. * lowest element in the high sublist). This algorithm offers guaranteed
  1104. * n*log(n) performance.
  1105. *
  1106. * @param a the array to be sorted.
  1107. * @param c the comparator to determine the order of the array. A
  1108. * <tt>null</tt> value indicates that the elements' <i>natural
  1109. * ordering</i> should be used.
  1110. * @throws ClassCastException if the array contains elements that are
  1111. * not <i>mutually comparable</i> using the specified comparator.
  1112. * @see Comparator
  1113. */
  1114. public static <T> void sort(T[] a, Comparator<? super T> c) {
  1115. T[] aux = (T[])a.clone();
  1116. if (c==null)
  1117. mergeSort(aux, a, 0, a.length, 0);
  1118. else
  1119. mergeSort(aux, a, 0, a.length, 0, c);
  1120. }
  1121. /**
  1122. * Sorts the specified range of the specified array of objects according
  1123. * to the order induced by the specified comparator. The range to be
  1124. * sorted extends from index <tt>fromIndex</tt>, inclusive, to index
  1125. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  1126. * range to be sorted is empty.) All elements in the range must be
  1127. * <i>mutually comparable</i> by the specified comparator (that is,
  1128. * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt>
  1129. * for any elements <tt>e1</tt> and <tt>e2</tt> in the range).<p>
  1130. *
  1131. * This sort is guaranteed to be <i>stable</i>: equal elements will
  1132. * not be reordered as a result of the sort.<p>
  1133. *
  1134. * The sorting algorithm is a modified mergesort (in which the merge is
  1135. * omitted if the highest element in the low sublist is less than the
  1136. * lowest element in the high sublist). This algorithm offers guaranteed
  1137. * n*log(n) performance.
  1138. *
  1139. * @param a the array to be sorted.
  1140. * @param fromIndex the index of the first element (inclusive) to be
  1141. * sorted.
  1142. * @param toIndex the index of the last element (exclusive) to be sorted.
  1143. * @param c the comparator to determine the order of the array. A
  1144. * <tt>null</tt> value indicates that the elements' <i>natural
  1145. * ordering</i> should be used.
  1146. * @throws ClassCastException if the array contains elements that are not
  1147. * <i>mutually comparable</i> using the specified comparator.
  1148. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1149. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1150. * <tt>toIndex > a.length</tt>
  1151. * @see Comparator
  1152. */
  1153. public static <T> void sort(T[] a, int fromIndex, int toIndex,
  1154. Comparator<? super T> c) {
  1155. rangeCheck(a.length, fromIndex, toIndex);
  1156. T[] aux = (T[])cloneSubarray(a, fromIndex, toIndex);
  1157. if (c==null)
  1158. mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
  1159. else
  1160. mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c);
  1161. }
  1162. /**
  1163. * Src is the source array that starts at index 0
  1164. * Dest is the (possibly larger) array destination with a possible offset
  1165. * low is the index in dest to start sorting
  1166. * high is the end index in dest to end sorting
  1167. * off is the offset into src corresponding to low in dest
  1168. */
  1169. private static void mergeSort(Object[] src,
  1170. Object[] dest,
  1171. int low, int high, int off,
  1172. Comparator c) {
  1173. int length = high - low;
  1174. // Insertion sort on smallest arrays
  1175. if (length < INSERTIONSORT_THRESHOLD) {
  1176. for (int i=low; i<high; i++)
  1177. for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
  1178. swap(dest, j, j-1);
  1179. return;
  1180. }
  1181. // Recursively sort halves of dest into src
  1182. int destLow = low;
  1183. int destHigh = high;
  1184. low += off;
  1185. high += off;
  1186. int mid = (low + high) >> 1;
  1187. mergeSort(dest, src, low, mid, -off, c);
  1188. mergeSort(dest, src, mid, high, -off, c);
  1189. // If list is already sorted, just copy from src to dest. This is an
  1190. // optimization that results in faster sorts for nearly ordered lists.
  1191. if (c.compare(src[mid-1], src[mid]) <= 0) {
  1192. System.arraycopy(src, low, dest, destLow, length);
  1193. return;
  1194. }
  1195. // Merge sorted halves (now in src) into dest
  1196. for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
  1197. if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
  1198. dest[i] = src[p++];
  1199. else
  1200. dest[i] = src[q++];
  1201. }
  1202. }
  1203. /**
  1204. * Check that fromIndex and toIndex are in range, and throw an
  1205. * appropriate exception if they aren't.
  1206. */
  1207. private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
  1208. if (fromIndex > toIndex)
  1209. throw new IllegalArgumentException("fromIndex(" + fromIndex +
  1210. ") > toIndex(" + toIndex+")");
  1211. if (fromIndex < 0)
  1212. throw new ArrayIndexOutOfBoundsException(fromIndex);
  1213. if (toIndex > arrayLen)
  1214. throw new ArrayIndexOutOfBoundsException(toIndex);
  1215. }
  1216. // Searching
  1217. /**
  1218. * Searches the specified array of longs for the specified value using the
  1219. * binary search algorithm. The array <strong>must</strong> be sorted (as
  1220. * by the <tt>sort</tt> method, above) prior to making this call. If it
  1221. * is not sorted, the results are undefined. If the array contains
  1222. * multiple elements with the specified value, there is no guarantee which
  1223. * one will be found.
  1224. *
  1225. * @param a the array to be searched.
  1226. * @param key the value to be searched for.
  1227. * @return index of the search key, if it is contained in the list;
  1228. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1229. * <i>insertion point</i> is defined as the point at which the
  1230. * key would be inserted into the list: the index of the first
  1231. * element greater than the key, or <tt>list.size()</tt>, if all
  1232. * elements in the list are less than the specified key. Note
  1233. * that this guarantees that the return value will be >= 0 if
  1234. * and only if the key is found.
  1235. * @see #sort(long[])
  1236. */
  1237. public static int binarySearch(long[] a, long key) {
  1238. int low = 0;
  1239. int high = a.length-1;
  1240. while (low <= high) {
  1241. int mid = (low + high) >> 1;
  1242. long midVal = a[mid];
  1243. if (midVal < key)
  1244. low = mid + 1;
  1245. else if (midVal > key)
  1246. high = mid - 1;
  1247. else
  1248. return mid; // key found
  1249. }
  1250. return -(low + 1); // key not found.
  1251. }
  1252. /**
  1253. * Searches the specified array of ints for the specified value using the
  1254. * binary search algorithm. The array <strong>must</strong> be sorted (as
  1255. * by the <tt>sort</tt> method, above) prior to making this call. If it
  1256. * is not sorted, the results are undefined. If the array contains
  1257. * multiple elements with the specified value, there is no guarantee which
  1258. * one will be found.
  1259. *
  1260. * @param a the array to be searched.
  1261. * @param key the value to be searched for.
  1262. * @return index of the search key, if it is contained in the list;
  1263. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1264. * <i>insertion point</i> is defined as the point at which the
  1265. * key would be inserted into the list: the index of the first
  1266. * element greater than the key, or <tt>list.size()</tt>, if all
  1267. * elements in the list are less than the specified key. Note
  1268. * that this guarantees that the return value will be >= 0 if
  1269. * and only if the key is found.
  1270. * @see #sort(int[])
  1271. */
  1272. public static int binarySearch(int[] a, int key) {
  1273. int low = 0;
  1274. int high = a.length-1;
  1275. while (low <= high) {
  1276. int mid = (low + high) >> 1;
  1277. int midVal = a[mid];
  1278. if (midVal < key)
  1279. low = mid + 1;
  1280. else if (midVal > key)
  1281. high = mid - 1;
  1282. else
  1283. return mid; // key found
  1284. }
  1285. return -(low + 1); // key not found.
  1286. }
  1287. /**
  1288. * Searches the specified array of shorts for the specified value using
  1289. * the binary search algorithm. The array <strong>must</strong> be sorted
  1290. * (as by the <tt>sort</tt> method, above) prior to making this call. If
  1291. * it is not sorted, the results are undefined. If the array contains
  1292. * multiple elements with the specified value, there is no guarantee which
  1293. * one will be found.
  1294. *
  1295. * @param a the array to be searched.
  1296. * @param key the value to be searched for.
  1297. * @return index of the search key, if it is contained in the list;
  1298. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1299. * <i>insertion point</i> is defined as the point at which the
  1300. * key would be inserted into the list: the index of the first
  1301. * element greater than the key, or <tt>list.size()</tt>, if all
  1302. * elements in the list are less than the specified key. Note
  1303. * that this guarantees that the return value will be >= 0 if
  1304. * and only if the key is found.
  1305. * @see #sort(short[])
  1306. */
  1307. public static int binarySearch(short[] a, short key) {
  1308. int low = 0;
  1309. int high = a.length-1;
  1310. while (low <= high) {
  1311. int mid = (low + high) >> 1;
  1312. short midVal = a[mid];
  1313. if (midVal < key)
  1314. low = mid + 1;
  1315. else if (midVal > key)
  1316. high = mid - 1;
  1317. else
  1318. return mid; // key found
  1319. }
  1320. return -(low + 1); // key not found.
  1321. }
  1322. /**
  1323. * Searches the specified array of chars for the specified value using the
  1324. * binary search algorithm. The array <strong>must</strong> be sorted (as
  1325. * by the <tt>sort</tt> method, above) prior to making this call. If it
  1326. * is not sorted, the results are undefined. If the array contains
  1327. * multiple elements with the specified value, there is no guarantee which
  1328. * one will be found.
  1329. *
  1330. * @param a the array to be searched.
  1331. * @param key the value to be searched for.
  1332. * @return index of the search key, if it is contained in the list;
  1333. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1334. * <i>insertion point</i> is defined as the point at which the
  1335. * key would be inserted into the list: the index of the first
  1336. * element greater than the key, or <tt>list.size()</tt>, if all
  1337. * elements in the list are less than the specified key. Note
  1338. * that this guarantees that the return value will be >= 0 if
  1339. * and only if the key is found.
  1340. * @see #sort(char[])
  1341. */
  1342. public static int binarySearch(char[] a, char key) {
  1343. int low = 0;
  1344. int high = a.length-1;
  1345. while (low <= high) {
  1346. int mid = (low + high) >> 1;
  1347. char midVal = a[mid];
  1348. if (midVal < key)
  1349. low = mid + 1;
  1350. else if (midVal > key)
  1351. high = mid - 1;
  1352. else
  1353. return mid; // key found
  1354. }
  1355. return -(low + 1); // key not found.
  1356. }
  1357. /**
  1358. * Searches the specified array of bytes for the specified value using the
  1359. * binary search algorithm. The array <strong>must</strong> be sorted (as
  1360. * by the <tt>sort</tt> method, above) prior to making this call. If it
  1361. * is not sorted, the results are undefined. If the array contains
  1362. * multiple elements with the specified value, there is no guarantee which
  1363. * one will be found.
  1364. *
  1365. * @param a the array to be searched.
  1366. * @param key the value to be searched for.
  1367. * @return index of the search key, if it is contained in the list;
  1368. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1369. * <i>insertion point</i> is defined as the point at which the
  1370. * key would be inserted into the list: the index of the first
  1371. * element greater than the key, or <tt>list.size()</tt>, if all
  1372. * elements in the list are less than the specified key. Note
  1373. * that this guarantees that the return value will be >= 0 if
  1374. * and only if the key is found.
  1375. * @see #sort(byte[])
  1376. */
  1377. public static int binarySearch(byte[] a, byte key) {
  1378. int low = 0;
  1379. int high = a.length-1;
  1380. while (low <= high) {
  1381. int mid = (low + high) >> 1;
  1382. byte midVal = a[mid];
  1383. if (midVal < key)
  1384. low = mid + 1;
  1385. else if (midVal > key)
  1386. high = mid - 1;
  1387. else
  1388. return mid; // key found
  1389. }
  1390. return -(low + 1); // key not found.
  1391. }
  1392. /**
  1393. * Searches the specified array of doubles for the specified value using
  1394. * the binary search algorithm. The array <strong>must</strong> be sorted
  1395. * (as by the <tt>sort</tt> method, above) prior to making this call. If
  1396. * it is not sorted, the results are undefined. If the array contains
  1397. * multiple elements with the specified value, there is no guarantee which
  1398. * one will be found. This method considers all NaN values to be
  1399. * equivalent and equal.
  1400. *
  1401. * @param a the array to be searched.
  1402. * @param key the value to be searched for.
  1403. * @return index of the search key, if it is contained in the list;
  1404. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1405. * <i>insertion point</i> is defined as the point at which the
  1406. * key would be inserted into the list: the index of the first
  1407. * element greater than the key, or <tt>list.size()</tt>, if all
  1408. * elements in the list are less than the specified key. Note
  1409. * that this guarantees that the return value will be >= 0 if
  1410. * and only if the key is found.
  1411. * @see #sort(double[])
  1412. */
  1413. public static int binarySearch(double[] a, double key) {
  1414. return binarySearch(a, key, 0, a.length-1);
  1415. }
  1416. private static int binarySearch(double[] a, double key, int low,int high) {
  1417. while (low <= high) {
  1418. int mid = (low + high) >> 1;
  1419. double midVal = a[mid];
  1420. int cmp;
  1421. if (midVal < key) {
  1422. cmp = -1; // Neither val is NaN, thisVal is smaller
  1423. } else if (midVal > key) {
  1424. cmp = 1; // Neither val is NaN, thisVal is larger
  1425. } else {
  1426. long midBits = Double.doubleToLongBits(midVal);
  1427. long keyBits = Double.doubleToLongBits(key);
  1428. cmp = (midBits == keyBits ? 0 : // Values are equal
  1429. (midBits < keyBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
  1430. 1)); // (0.0, -0.0) or (NaN, !NaN)
  1431. }
  1432. if (cmp < 0)
  1433. low = mid + 1;
  1434. else if (cmp > 0)
  1435. high = mid - 1;
  1436. else
  1437. return mid; // key found
  1438. }
  1439. return -(low + 1); // key not found.
  1440. }
  1441. /**
  1442. * Searches the specified array of floats for the specified value using
  1443. * the binary search algorithm. The array <strong>must</strong> be sorted
  1444. * (as by the <tt>sort</tt> method, above) prior to making this call. If
  1445. * it is not sorted, the results are undefined. If the array contains
  1446. * multiple elements with the specified value, there is no guarantee which
  1447. * one will be found. This method considers all NaN values to be
  1448. * equivalent and equal.
  1449. *
  1450. * @param a the array to be searched.
  1451. * @param key the value to be searched for.
  1452. * @return index of the search key, if it is contained in the list;
  1453. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1454. * <i>insertion point</i> is defined as the point at which the
  1455. * key would be inserted into the list: the index of the first
  1456. * element greater than the key, or <tt>list.size()</tt>, if all
  1457. * elements in the list are less than the specified key. Note
  1458. * that this guarantees that the return value will be >= 0 if
  1459. * and only if the key is found.
  1460. * @see #sort(float[])
  1461. */
  1462. public static int binarySearch(float[] a, float key) {
  1463. return binarySearch(a, key, 0, a.length-1);
  1464. }
  1465. private static int binarySearch(float[] a, float key, int low,int high) {
  1466. while (low <= high) {
  1467. int mid = (low + high) >> 1;
  1468. float midVal = a[mid];
  1469. int cmp;
  1470. if (midVal < key) {
  1471. cmp = -1; // Neither val is NaN, thisVal is smaller
  1472. } else if (midVal > key) {
  1473. cmp = 1; // Neither val is NaN, thisVal is larger
  1474. } else {
  1475. int midBits = Float.floatToIntBits(midVal);
  1476. int keyBits = Float.floatToIntBits(key);
  1477. cmp = (midBits == keyBits ? 0 : // Values are equal
  1478. (midBits < keyBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
  1479. 1)); // (0.0, -0.0) or (NaN, !NaN)
  1480. }
  1481. if (cmp < 0)
  1482. low = mid + 1;
  1483. else if (cmp > 0)
  1484. high = mid - 1;
  1485. else
  1486. return mid; // key found
  1487. }
  1488. return -(low + 1); // key not found.
  1489. }
  1490. /**
  1491. * Searches the specified array for the specified object using the binary
  1492. * search algorithm. The array must be sorted into ascending order
  1493. * according to the <i>natural ordering</i> of its elements (as by
  1494. * <tt>Sort(Object[]</tt>), above) prior to making this call. If it is
  1495. * not sorted, the results are undefined.
  1496. * (If the array contains elements that are not mutually comparable (for
  1497. * example,strings and integers), it <i>cannot</i> be sorted according
  1498. * to the natural order of its elements, hence results are undefined.)
  1499. * If the array contains multiple
  1500. * elements equal to the specified object, there is no guarantee which
  1501. * one will be found.
  1502. *
  1503. * @param a the array to be searched.
  1504. * @param key the value to be searched for.
  1505. * @return index of the search key, if it is contained in the list;
  1506. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1507. * <i>insertion point</i> is defined as the point at which the
  1508. * key would be inserted into the list: the index of the first
  1509. * element greater than the key, or <tt>list.size()</tt>, if all
  1510. * elements in the list are less than the specified key. Note
  1511. * that this guarantees that the return value will be >= 0 if
  1512. * and only if the key is found.
  1513. * @throws ClassCastException if the search key in not comparable to the
  1514. * elements of the array.
  1515. * @see Comparable
  1516. * @see #sort(Object[])
  1517. */
  1518. public static int binarySearch(Object[] a, Object key) {
  1519. int low = 0;
  1520. int high = a.length-1;
  1521. while (low <= high) {
  1522. int mid = (low + high) >> 1;
  1523. Comparable midVal = (Comparable)a[mid];
  1524. int cmp = midVal.compareTo(key);
  1525. if (cmp < 0)
  1526. low = mid + 1;
  1527. else if (cmp > 0)
  1528. high = mid - 1;
  1529. else
  1530. return mid; // key found
  1531. }
  1532. return -(low + 1); // key not found.
  1533. }
  1534. /**
  1535. * Searches the specified array for the specified object using the binary
  1536. * search algorithm. The array must be sorted into ascending order
  1537. * according to the specified comparator (as by the <tt>Sort(Object[],
  1538. * Comparator)</tt> method, above), prior to making this call. If it is
  1539. * not sorted, the results are undefined.
  1540. * If the array contains multiple
  1541. * elements equal to the specified object, there is no guarantee which one
  1542. * will be found.
  1543. *
  1544. * @param a the array to be searched.
  1545. * @param key the value to be searched for.
  1546. * @param c the comparator by which the array is ordered. A
  1547. * <tt>null</tt> value indicates that the elements' <i>natural
  1548. * ordering</i> should be used.
  1549. * @return index of the search key, if it is contained in the list;
  1550. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  1551. * <i>insertion point</i> is defined as the point at which the
  1552. * key would be inserted into the list: the index of the first
  1553. * element greater than the key, or <tt>list.size()</tt>, if all
  1554. * elements in the list are less than the specified key. Note
  1555. * that this guarantees that the return value will be >= 0 if
  1556. * and only if the key is found.
  1557. * @throws ClassCastException if the array contains elements that are not
  1558. * <i>mutually comparable</i> using the specified comparator,
  1559. * or the search key in not mutually comparable with the
  1560. * elements of the array using this comparator.
  1561. * @see Comparable
  1562. * @see #sort(Object[], Comparator)
  1563. */
  1564. public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c) {
  1565. if (c==null) {
  1566. return binarySearch(a, key);
  1567. }
  1568. int low = 0;
  1569. int high = a.length-1;
  1570. while (low <= high) {
  1571. int mid = (low + high) >> 1;
  1572. T midVal = a[mid];
  1573. int cmp = c.compare(midVal, key);
  1574. if (cmp < 0)
  1575. low = mid + 1;
  1576. else if (cmp > 0)
  1577. high = mid - 1;
  1578. else
  1579. return mid; // key found
  1580. }
  1581. return -(low + 1); // key not found.
  1582. }
  1583. // Equality Testing
  1584. /**
  1585. * Returns <tt>true</tt> if the two specified arrays of longs are
  1586. * <i>equal</i> to one another. Two arrays are considered equal if both
  1587. * arrays contain the same number of elements, and all corresponding pairs
  1588. * of elements in the two arrays are equal. In other words, two arrays
  1589. * are equal if they contain the same elements in the same order. Also,
  1590. * two array references are considered equal if both are <tt>null</tt>.<p>
  1591. *
  1592. * @param a one array to be tested for equality.
  1593. * @param a2 the other array to be tested for equality.
  1594. * @return <tt>true</tt> if the two arrays are equal.
  1595. */
  1596. public static boolean equals(long[] a, long[] a2) {
  1597. if (a==a2)
  1598. return true;
  1599. if (a==null || a2==null)
  1600. return false;
  1601. int length = a.length;
  1602. if (a2.length != length)
  1603. return false;
  1604. for (int i=0; i<length; i++)
  1605. if (a[i] != a2[i])
  1606. return false;
  1607. return true;
  1608. }
  1609. /**
  1610. * Returns <tt>true</tt> if the two specified arrays of ints are
  1611. * <i>equal</i> to one another. Two arrays are considered equal if both
  1612. * arrays contain the same number of elements, and all corresponding pairs
  1613. * of elements in the two arrays are equal. In other words, two arrays
  1614. * are equal if they contain the same elements in the same order. Also,
  1615. * two array references are considered equal if both are <tt>null</tt>.<p>
  1616. *
  1617. * @param a one array to be tested for equality.
  1618. * @param a2 the other array to be tested for equality.
  1619. * @return <tt>true</tt> if the two arrays are equal.
  1620. */
  1621. public static boolean equals(int[] a, int[] a2) {
  1622. if (a==a2)
  1623. return true;
  1624. if (a==null || a2==null)
  1625. return false;
  1626. int length = a.length;
  1627. if (a2.length != length)
  1628. return false;
  1629. for (int i=0; i<length; i++)
  1630. if (a[i] != a2[i])
  1631. return false;
  1632. return true;
  1633. }
  1634. /**
  1635. * Returns <tt>true</tt> if the two specified arrays of shorts are
  1636. * <i>equal</i> to one another. Two arrays are considered equal if both
  1637. * arrays contain the same number of elements, and all corresponding pairs
  1638. * of elements in the two arrays are equal. In other words, two arrays
  1639. * are equal if they contain the same elements in the same order. Also,
  1640. * two array references are considered equal if both are <tt>null</tt>.<p>
  1641. *
  1642. * @param a one array to be tested for equality.
  1643. * @param a2 the other array to be tested for equality.
  1644. * @return <tt>true</tt> if the two arrays are equal.
  1645. */
  1646. public static boolean equals(short[] a, short a2[]) {
  1647. if (a==a2)
  1648. return true;
  1649. if (a==null || a2==null)
  1650. return false;
  1651. int length = a.length;
  1652. if (a2.length != length)
  1653. return false;
  1654. for (int i=0; i<length; i++)
  1655. if (a[i] != a2[i])
  1656. return false;
  1657. return true;
  1658. }
  1659. /**
  1660. * Returns <tt>true</tt> if the two specified arrays of chars are
  1661. * <i>equal</i> to one another. Two arrays are considered equal if both
  1662. * arrays contain the same number of elements, and all corresponding pairs
  1663. * of elements in the two arrays are equal. In other words, two arrays
  1664. * are equal if they contain the same elements in the same order. Also,
  1665. * two array references are considered equal if both are <tt>null</tt>.<p>
  1666. *
  1667. * @param a one array to be tested for equality.
  1668. * @param a2 the other array to be tested for equality.
  1669. * @return <tt>true</tt> if the two arrays are equal.
  1670. */
  1671. public static boolean equals(char[] a, char[] a2) {
  1672. if (a==a2)
  1673. return true;
  1674. if (a==null || a2==null)
  1675. return false;
  1676. int length = a.length;
  1677. if (a2.length != length)
  1678. return false;
  1679. for (int i=0; i<length; i++)
  1680. if (a[i] != a2[i])
  1681. return false;
  1682. return true;
  1683. }
  1684. /**
  1685. * Returns <tt>true</tt> if the two specified arrays of bytes are
  1686. * <i>equal</i> to one another. Two arrays are considered equal if both
  1687. * arrays contain the same number of elements, and all corresponding pairs
  1688. * of elements in the two arrays are equal. In other words, two arrays
  1689. * are equal if they contain the same elements in the same order. Also,
  1690. * two array references are considered equal if both are <tt>null</tt>.<p>
  1691. *
  1692. * @param a one array to be tested for equality.
  1693. * @param a2 the other array to be tested for equality.
  1694. * @return <tt>true</tt> if the two arrays are equal.
  1695. */
  1696. public static boolean equals(byte[] a, byte[] a2) {
  1697. if (a==a2)
  1698. return true;
  1699. if (a==null || a2==null)
  1700. return false;
  1701. int length = a.length;
  1702. if (a2.length != length)
  1703. return false;
  1704. for (int i=0; i<length; i++)
  1705. if (a[i] != a2[i])
  1706. return false;
  1707. return true;
  1708. }
  1709. /**
  1710. * Returns <tt>true</tt> if the two specified arrays of booleans are
  1711. * <i>equal</i> to one another. Two arrays are considered equal if both
  1712. * arrays contain the same number of elements, and all corresponding pairs
  1713. * of elements in the two arrays are equal. In other words, two arrays
  1714. * are equal if they contain the same elements in the same order. Also,
  1715. * two array references are considered equal if both are <tt>null</tt>.<p>
  1716. *
  1717. * @param a one array to be tested for equality.
  1718. * @param a2 the other array to be tested for equality.
  1719. * @return <tt>true</tt> if the two arrays are equal.
  1720. */
  1721. public static boolean equals(boolean[] a, boolean[] a2) {
  1722. if (a==a2)
  1723. return true;
  1724. if (a==null || a2==null)
  1725. return false;
  1726. int length = a.length;
  1727. if (a2.length != length)
  1728. return false;
  1729. for (int i=0; i<length; i++)
  1730. if (a[i] != a2[i])
  1731. return false;
  1732. return true;
  1733. }
  1734. /**
  1735. * Returns <tt>true</tt> if the two specified arrays of doubles are
  1736. * <i>equal</i> to one another. Two arrays are considered equal if both
  1737. * arrays contain the same number of elements, and all corresponding pairs
  1738. * of elements in the two arrays are equal. In other words, two arrays
  1739. * are equal if they contain the same elements in the same order. Also,
  1740. * two array references are considered equal if both are <tt>null</tt>.<p>
  1741. *
  1742. * Two doubles <tt>d1</tt> and <tt>d2</tt> are considered equal if:
  1743. * <pre> <tt>new Double(d1).equals(new Double(d2))</tt></pre>
  1744. * (Unlike the <tt>==</tt> operator, this method considers
  1745. * <tt>NaN</tt> equals to itself, and 0.0d unequal to -0.0d.)
  1746. *
  1747. * @param a one array to be tested for equality.
  1748. * @param a2 the other array to be tested for equality.
  1749. * @return <tt>true</tt> if the two arrays are equal.
  1750. * @see Double#equals(Object)
  1751. */
  1752. public static boolean equals(double[] a, double[] a2) {
  1753. if (a==a2)
  1754. return true;
  1755. if (a==null || a2==null)
  1756. return false;
  1757. int length = a.length;
  1758. if (a2.length != length)
  1759. return false;
  1760. for (int i=0; i<length; i++)
  1761. if (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i]))
  1762. return false;
  1763. return true;
  1764. }
  1765. /**
  1766. * Returns <tt>true</tt> if the two specified arrays of floats are
  1767. * <i>equal</i> to one another. Two arrays are considered equal if both
  1768. * arrays contain the same number of elements, and all corresponding pairs
  1769. * of elements in the two arrays are equal. In other words, two arrays
  1770. * are equal if they contain the same elements in the same order. Also,
  1771. * two array references are considered equal if both are <tt>null</tt>.<p>
  1772. *
  1773. * Two floats <tt>f1</tt> and <tt>f2</tt> are considered equal if:
  1774. * <pre> <tt>new Float(f1).equals(new Float(f2))</tt></pre>
  1775. * (Unlike the <tt>==</tt> operator, this method considers
  1776. * <tt>NaN</tt> equals to itself, and 0.0f unequal to -0.0f.)
  1777. *
  1778. * @param a one array to be tested for equality.
  1779. * @param a2 the other array to be tested for equality.
  1780. * @return <tt>true</tt> if the two arrays are equal.
  1781. * @see Float#equals(Object)
  1782. */
  1783. public static boolean equals(float[] a, float[] a2) {
  1784. if (a==a2)
  1785. return true;
  1786. if (a==null || a2==null)
  1787. return false;
  1788. int length = a.length;
  1789. if (a2.length != length)
  1790. return false;
  1791. for (int i=0; i<length; i++)
  1792. if (Float.floatToIntBits(a[i])!=Float.floatToIntBits(a2[i]))
  1793. return false;
  1794. return true;
  1795. }
  1796. /**
  1797. * Returns <tt>true</tt> if the two specified arrays of Objects are
  1798. * <i>equal</i> to one another. The two arrays are considered equal if
  1799. * both arrays contain the same number of elements, and all corresponding
  1800. * pairs of elements in the two arrays are equal. Two objects <tt>e1</tt>
  1801. * and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null
  1802. * : e1.equals(e2))</tt>. In other words, the two arrays are equal if
  1803. * they contain the same elements in the same order. Also, two array
  1804. * references are considered equal if both are <tt>null</tt>.<p>
  1805. *
  1806. * @param a one array to be tested for equality.
  1807. * @param a2 the other array to be tested for equality.
  1808. * @return <tt>true</tt> if the two arrays are equal.
  1809. */
  1810. public static boolean equals(Object[] a, Object[] a2) {
  1811. if (a==a2)
  1812. return true;
  1813. if (a==null || a2==null)
  1814. return false;
  1815. int length = a.length;
  1816. if (a2.length != length)
  1817. return false;
  1818. for (int i=0; i<length; i++) {
  1819. Object o1 = a[i];
  1820. Object o2 = a2[i];
  1821. if (!(o1==null ? o2==null : o1.equals(o2)))
  1822. return false;
  1823. }
  1824. return true;
  1825. }
  1826. // Filling
  1827. /**
  1828. * Assigns the specified long value to each element of the specified array
  1829. * of longs.
  1830. *
  1831. * @param a the array to be filled.
  1832. * @param val the value to be stored in all elements of the array.
  1833. */
  1834. public static void fill(long[] a, long val) {
  1835. fill(a, 0, a.length, val);
  1836. }
  1837. /**
  1838. * Assigns the specified long value to each element of the specified
  1839. * range of the specified array of longs. The range to be filled
  1840. * extends from index <tt>fromIndex</tt>, inclusive, to index
  1841. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  1842. * range to be filled is empty.)
  1843. *
  1844. * @param a the array to be filled.
  1845. * @param fromIndex the index of the first element (inclusive) to be
  1846. * filled with the specified value.
  1847. * @param toIndex the index of the last element (exclusive) to be
  1848. * filled with the specified value.
  1849. * @param val the value to be stored in all elements of the array.
  1850. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1851. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1852. * <tt>toIndex > a.length</tt>
  1853. */
  1854. public static void fill(long[] a, int fromIndex, int toIndex, long val) {
  1855. rangeCheck(a.length, fromIndex, toIndex);
  1856. for (int i=fromIndex; i<toIndex; i++)
  1857. a[i] = val;
  1858. }
  1859. /**
  1860. * Assigns the specified int value to each element of the specified array
  1861. * of ints.
  1862. *
  1863. * @param a the array to be filled.
  1864. * @param val the value to be stored in all elements of the array.
  1865. */
  1866. public static void fill(int[] a, int val) {
  1867. fill(a, 0, a.length, val);
  1868. }
  1869. /**
  1870. * Assigns the specified int value to each element of the specified
  1871. * range of the specified array of ints. The range to be filled
  1872. * extends from index <tt>fromIndex</tt>, inclusive, to index
  1873. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  1874. * range to be filled is empty.)
  1875. *
  1876. * @param a the array to be filled.
  1877. * @param fromIndex the index of the first element (inclusive) to be
  1878. * filled with the specified value.
  1879. * @param toIndex the index of the last element (exclusive) to be
  1880. * filled with the specified value.
  1881. * @param val the value to be stored in all elements of the array.
  1882. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1883. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1884. * <tt>toIndex > a.length</tt>
  1885. */
  1886. public static void fill(int[] a, int fromIndex, int toIndex, int val) {
  1887. rangeCheck(a.length, fromIndex, toIndex);
  1888. for (int i=fromIndex; i<toIndex; i++)
  1889. a[i] = val;
  1890. }
  1891. /**
  1892. * Assigns the specified short value to each element of the specified array
  1893. * of shorts.
  1894. *
  1895. * @param a the array to be filled.
  1896. * @param val the value to be stored in all elements of the array.
  1897. */
  1898. public static void fill(short[] a, short val) {
  1899. fill(a, 0, a.length, val);
  1900. }
  1901. /**
  1902. * Assigns the specified short value to each element of the specified
  1903. * range of the specified array of shorts. The range to be filled
  1904. * extends from index <tt>fromIndex</tt>, inclusive, to index
  1905. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  1906. * range to be filled is empty.)
  1907. *
  1908. * @param a the array to be filled.
  1909. * @param fromIndex the index of the first element (inclusive) to be
  1910. * filled with the specified value.
  1911. * @param toIndex the index of the last element (exclusive) to be
  1912. * filled with the specified value.
  1913. * @param val the value to be stored in all elements of the array.
  1914. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1915. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1916. * <tt>toIndex > a.length</tt>
  1917. */
  1918. public static void fill(short[] a, int fromIndex, int toIndex, short val) {
  1919. rangeCheck(a.length, fromIndex, toIndex);
  1920. for (int i=fromIndex; i<toIndex; i++)
  1921. a[i] = val;
  1922. }
  1923. /**
  1924. * Assigns the specified char value to each element of the specified array
  1925. * of chars.
  1926. *
  1927. * @param a the array to be filled.
  1928. * @param val the value to be stored in all elements of the array.
  1929. */
  1930. public static void fill(char[] a, char val) {
  1931. fill(a, 0, a.length, val);
  1932. }
  1933. /**
  1934. * Assigns the specified char value to each element of the specified
  1935. * range of the specified array of chars. The range to be filled
  1936. * extends from index <tt>fromIndex</tt>, inclusive, to index
  1937. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  1938. * range to be filled is empty.)
  1939. *
  1940. * @param a the array to be filled.
  1941. * @param fromIndex the index of the first element (inclusive) to be
  1942. * filled with the specified value.
  1943. * @param toIndex the index of the last element (exclusive) to be
  1944. * filled with the specified value.
  1945. * @param val the value to be stored in all elements of the array.
  1946. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1947. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1948. * <tt>toIndex > a.length</tt>
  1949. */
  1950. public static void fill(char[] a, int fromIndex, int toIndex, char val) {
  1951. rangeCheck(a.length, fromIndex, toIndex);
  1952. for (int i=fromIndex; i<toIndex; i++)
  1953. a[i] = val;
  1954. }
  1955. /**
  1956. * Assigns the specified byte value to each element of the specified array
  1957. * of bytes.
  1958. *
  1959. * @param a the array to be filled.
  1960. * @param val the value to be stored in all elements of the array.
  1961. */
  1962. public static void fill(byte[] a, byte val) {
  1963. fill(a, 0, a.length, val);
  1964. }
  1965. /**
  1966. * Assigns the specified byte value to each element of the specified
  1967. * range of the specified array of bytes. The range to be filled
  1968. * extends from index <tt>fromIndex</tt>, inclusive, to index
  1969. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  1970. * range to be filled is empty.)
  1971. *
  1972. * @param a the array to be filled.
  1973. * @param fromIndex the index of the first element (inclusive) to be
  1974. * filled with the specified value.
  1975. * @param toIndex the index of the last element (exclusive) to be
  1976. * filled with the specified value.
  1977. * @param val the value to be stored in all elements of the array.
  1978. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  1979. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  1980. * <tt>toIndex > a.length</tt>
  1981. */
  1982. public static void fill(byte[] a, int fromIndex, int toIndex, byte val) {
  1983. rangeCheck(a.length, fromIndex, toIndex);
  1984. for (int i=fromIndex; i<toIndex; i++)
  1985. a[i] = val;
  1986. }
  1987. /**
  1988. * Assigns the specified boolean value to each element of the specified
  1989. * array of booleans.
  1990. *
  1991. * @param a the array to be filled.
  1992. * @param val the value to be stored in all elements of the array.
  1993. */
  1994. public static void fill(boolean[] a, boolean val) {
  1995. fill(a, 0, a.length, val);
  1996. }
  1997. /**
  1998. * Assigns the specified boolean value to each element of the specified
  1999. * range of the specified array of booleans. The range to be filled
  2000. * extends from index <tt>fromIndex</tt>, inclusive, to index
  2001. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  2002. * range to be filled is empty.)
  2003. *
  2004. * @param a the array to be filled.
  2005. * @param fromIndex the index of the first element (inclusive) to be
  2006. * filled with the specified value.
  2007. * @param toIndex the index of the last element (exclusive) to be
  2008. * filled with the specified value.
  2009. * @param val the value to be stored in all elements of the array.
  2010. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  2011. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  2012. * <tt>toIndex > a.length</tt>
  2013. */
  2014. public static void fill(boolean[] a, int fromIndex, int toIndex,
  2015. boolean val) {
  2016. rangeCheck(a.length, fromIndex, toIndex);
  2017. for (int i=fromIndex; i<toIndex; i++)
  2018. a[i] = val;
  2019. }
  2020. /**
  2021. * Assigns the specified double value to each element of the specified
  2022. * array of doubles.
  2023. *
  2024. * @param a the array to be filled.
  2025. * @param val the value to be stored in all elements of the array.
  2026. */
  2027. public static void fill(double[] a, double val) {
  2028. fill(a, 0, a.length, val);
  2029. }
  2030. /**
  2031. * Assigns the specified double value to each element of the specified
  2032. * range of the specified array of doubles. The range to be filled
  2033. * extends from index <tt>fromIndex</tt>, inclusive, to index
  2034. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  2035. * range to be filled is empty.)
  2036. *
  2037. * @param a the array to be filled.
  2038. * @param fromIndex the index of the first element (inclusive) to be
  2039. * filled with the specified value.
  2040. * @param toIndex the index of the last element (exclusive) to be
  2041. * filled with the specified value.
  2042. * @param val the value to be stored in all elements of the array.
  2043. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  2044. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  2045. * <tt>toIndex > a.length</tt>
  2046. */
  2047. public static void fill(double[] a, int fromIndex, int toIndex,double val){
  2048. rangeCheck(a.length, fromIndex, toIndex);
  2049. for (int i=fromIndex; i<toIndex; i++)
  2050. a[i] = val;
  2051. }
  2052. /**
  2053. * Assigns the specified float value to each element of the specified array
  2054. * of floats.
  2055. *
  2056. * @param a the array to be filled.
  2057. * @param val the value to be stored in all elements of the array.
  2058. */
  2059. public static void fill(float[] a, float val) {
  2060. fill(a, 0, a.length, val);
  2061. }
  2062. /**
  2063. * Assigns the specified float value to each element of the specified
  2064. * range of the specified array of floats. The range to be filled
  2065. * extends from index <tt>fromIndex</tt>, inclusive, to index
  2066. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  2067. * range to be filled is empty.)
  2068. *
  2069. * @param a the array to be filled.
  2070. * @param fromIndex the index of the first element (inclusive) to be
  2071. * filled with the specified value.
  2072. * @param toIndex the index of the last element (exclusive) to be
  2073. * filled with the specified value.
  2074. * @param val the value to be stored in all elements of the array.
  2075. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  2076. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  2077. * <tt>toIndex > a.length</tt>
  2078. */
  2079. public static void fill(float[] a, int fromIndex, int toIndex, float val) {
  2080. rangeCheck(a.length, fromIndex, toIndex);
  2081. for (int i=fromIndex; i<toIndex; i++)
  2082. a[i] = val;
  2083. }
  2084. /**
  2085. * Assigns the specified Object reference to each element of the specified
  2086. * array of Objects.
  2087. *
  2088. * @param a the array to be filled.
  2089. * @param val the value to be stored in all elements of the array.
  2090. */
  2091. public static void fill(Object[] a, Object val) {
  2092. Arrays.fill(a, 0, a.length, val);
  2093. }
  2094. /**
  2095. * Assigns the specified Object reference to each element of the specified
  2096. * range of the specified array of Objects. The range to be filled
  2097. * extends from index <tt>fromIndex</tt>, inclusive, to index
  2098. * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the
  2099. * range to be filled is empty.)
  2100. *
  2101. * @param a the array to be filled.
  2102. * @param fromIndex the index of the first element (inclusive) to be
  2103. * filled with the specified value.
  2104. * @param toIndex the index of the last element (exclusive) to be
  2105. * filled with the specified value.
  2106. * @param val the value to be stored in all elements of the array.
  2107. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt>
  2108. * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or
  2109. * <tt>toIndex > a.length</tt>
  2110. */
  2111. public static void fill(Object[] a, int fromIndex, int toIndex, Object val) {
  2112. rangeCheck(a.length, fromIndex, toIndex);
  2113. for (int i=fromIndex; i<toIndex; i++)
  2114. a[i] = val;
  2115. }
  2116. // Misc
  2117. /**
  2118. * Returns a fixed-size list backed by the specified array. (Changes to
  2119. * the returned list "write through" to the array.) This method acts
  2120. * as bridge between array-based and collection-based APIs, in
  2121. * combination with <tt>Collection.toArray</tt>. The returned list is
  2122. * serializable and implements {@link RandomAccess}.
  2123. *
  2124. * <p>This method also provides a convenient way to create a fixed-size
  2125. * list initialized to contain several elements:
  2126. * <pre>
  2127. * List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
  2128. * </pre>
  2129. *
  2130. * @param a the array by which the list will be backed.
  2131. * @return a list view of the specified array.
  2132. * @see Collection#toArray()
  2133. */
  2134. public static <T> List<T> asList(T... a) {
  2135. return new ArrayList<T>(a);
  2136. }
  2137. /**
  2138. * @serial include
  2139. */
  2140. private static class ArrayList<E> extends AbstractList<E>
  2141. implements RandomAccess, java.io.Serializable
  2142. {
  2143. private static final long serialVersionUID = -2764017481108945198L;
  2144. private Object[] a;
  2145. ArrayList(E[] array) {
  2146. if (array==null)
  2147. throw new NullPointerException();
  2148. a = array;
  2149. }
  2150. public int size() {
  2151. return a.length;
  2152. }
  2153. public Object[] toArray() {
  2154. return (Object[])a.clone();
  2155. }
  2156. public E get(int index) {
  2157. return (E)a[index];
  2158. }
  2159. public E set(int index, E element) {
  2160. Object oldValue = a[index];
  2161. a[index] = element;
  2162. return (E)oldValue;
  2163. }
  2164. public int indexOf(Object o) {
  2165. if (o==null) {
  2166. for (int i=0; i<a.length; i++)
  2167. if (a[i]==null)
  2168. return i;
  2169. } else {
  2170. for (int i=0; i<a.length; i++)
  2171. if (o.equals(a[i]))
  2172. return i;
  2173. }
  2174. return -1;
  2175. }
  2176. public boolean contains(Object o) {
  2177. return indexOf(o) != -1;
  2178. }
  2179. }
  2180. /**
  2181. * Returns a hash code based on the contents of the specified array.
  2182. * For any two <tt>long</tt> arrays <tt>a</tt> and <tt>b</tt>
  2183. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2184. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2185. *
  2186. * <p>The value returned by this method is the same value that would be
  2187. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2188. * method on a {@link List} containing a sequence of {@link Long}
  2189. * instances representing the elements of <tt>a</tt> in the same order.
  2190. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2191. *
  2192. * @param a the array whose hash value to compute
  2193. * @return a content-based hash code for <tt>a</tt>
  2194. * @since 1.5
  2195. */
  2196. public static int hashCode(long a[]) {
  2197. if (a == null)
  2198. return 0;
  2199. int result = 1;
  2200. for (long element : a) {
  2201. int elementHash = (int)(element ^ (element >>> 32));
  2202. result = 31 * result + elementHash;
  2203. }
  2204. return result;
  2205. }
  2206. /**
  2207. * Returns a hash code based on the contents of the specified array.
  2208. * For any two non-null <tt>int</tt> arrays <tt>a</tt> and <tt>b</tt>
  2209. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2210. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2211. *
  2212. * <p>The value returned by this method is the same value that would be
  2213. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2214. * method on a {@link List} containing a sequence of {@link Integer}
  2215. * instances representing the elements of <tt>a</tt> in the same order.
  2216. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2217. *
  2218. * @param a the array whose hash value to compute
  2219. * @return a content-based hash code for <tt>a</tt>
  2220. * @since 1.5
  2221. */
  2222. public static int hashCode(int a[]) {
  2223. if (a == null)
  2224. return 0;
  2225. int result = 1;
  2226. for (int element : a)
  2227. result = 31 * result + element;
  2228. return result;
  2229. }
  2230. /**
  2231. * Returns a hash code based on the contents of the specified array.
  2232. * For any two <tt>short</tt> arrays <tt>a</tt> and <tt>b</tt>
  2233. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2234. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2235. *
  2236. * <p>The value returned by this method is the same value that would be
  2237. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2238. * method on a {@link List} containing a sequence of {@link Short}
  2239. * instances representing the elements of <tt>a</tt> in the same order.
  2240. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2241. *
  2242. * @param a the array whose hash value to compute
  2243. * @return a content-based hash code for <tt>a</tt>
  2244. * @since 1.5
  2245. */
  2246. public static int hashCode(short a[]) {
  2247. if (a == null)
  2248. return 0;
  2249. int result = 1;
  2250. for (short element : a)
  2251. result = 31 * result + element;
  2252. return result;
  2253. }
  2254. /**
  2255. * Returns a hash code based on the contents of the specified array.
  2256. * For any two <tt>char</tt> arrays <tt>a</tt> and <tt>b</tt>
  2257. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2258. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2259. *
  2260. * <p>The value returned by this method is the same value that would be
  2261. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2262. * method on a {@link List} containing a sequence of {@link Character}
  2263. * instances representing the elements of <tt>a</tt> in the same order.
  2264. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2265. *
  2266. * @param a the array whose hash value to compute
  2267. * @return a content-based hash code for <tt>a</tt>
  2268. * @since 1.5
  2269. */
  2270. public static int hashCode(char a[]) {
  2271. if (a == null)
  2272. return 0;
  2273. int result = 1;
  2274. for (char element : a)
  2275. result = 31 * result + element;
  2276. return result;
  2277. }
  2278. /**
  2279. * Returns a hash code based on the contents of the specified array.
  2280. * For any two <tt>byte</tt> arrays <tt>a</tt> and <tt>b</tt>
  2281. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2282. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2283. *
  2284. * <p>The value returned by this method is the same value that would be
  2285. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2286. * method on a {@link List} containing a sequence of {@link Byte}
  2287. * instances representing the elements of <tt>a</tt> in the same order.
  2288. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2289. *
  2290. * @param a the array whose hash value to compute
  2291. * @return a content-based hash code for <tt>a</tt>
  2292. * @since 1.5
  2293. */
  2294. public static int hashCode(byte a[]) {
  2295. if (a == null)
  2296. return 0;
  2297. int result = 1;
  2298. for (byte element : a)
  2299. result = 31 * result + element;
  2300. return result;
  2301. }
  2302. /**
  2303. * Returns a hash code based on the contents of the specified array.
  2304. * For any two <tt>boolean</tt> arrays <tt>a</tt> and <tt>b</tt>
  2305. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2306. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2307. *
  2308. * <p>The value returned by this method is the same value that would be
  2309. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2310. * method on a {@link List} containing a sequence of {@link Boolean}
  2311. * instances representing the elements of <tt>a</tt> in the same order.
  2312. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2313. *
  2314. * @param a the array whose hash value to compute
  2315. * @return a content-based hash code for <tt>a</tt>
  2316. * @since 1.5
  2317. */
  2318. public static int hashCode(boolean a[]) {
  2319. if (a == null)
  2320. return 0;
  2321. int result = 1;
  2322. for (boolean element : a)
  2323. result = 31 * result + (element ? 1231 : 1237);
  2324. return result;
  2325. }
  2326. /**
  2327. * Returns a hash code based on the contents of the specified array.
  2328. * For any two <tt>float</tt> arrays <tt>a</tt> and <tt>b</tt>
  2329. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2330. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2331. *
  2332. * <p>The value returned by this method is the same value that would be
  2333. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2334. * method on a {@link List} containing a sequence of {@link Float}
  2335. * instances representing the elements of <tt>a</tt> in the same order.
  2336. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2337. *
  2338. * @param a the array whose hash value to compute
  2339. * @return a content-based hash code for <tt>a</tt>
  2340. * @since 1.5
  2341. */
  2342. public static int hashCode(float a[]) {
  2343. if (a == null)
  2344. return 0;
  2345. int result = 1;
  2346. for (float element : a)
  2347. result = 31 * result + Float.floatToIntBits(element);
  2348. return result;
  2349. }
  2350. /**
  2351. * Returns a hash code based on the contents of the specified array.
  2352. * For any two <tt>double</tt> arrays <tt>a</tt> and <tt>b</tt>
  2353. * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2354. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2355. *
  2356. * <p>The value returned by this method is the same value that would be
  2357. * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>}
  2358. * method on a {@link List} containing a sequence of {@link Double}
  2359. * instances representing the elements of <tt>a</tt> in the same order.
  2360. * If <tt>a</tt> is <tt>null</tt>, this method returns 0.
  2361. *
  2362. * @param a the array whose hash value to compute
  2363. * @return a content-based hash code for <tt>a</tt>
  2364. * @since 1.5
  2365. */
  2366. public static int hashCode(double a[]) {
  2367. if (a == null)
  2368. return 0;
  2369. int result = 1;
  2370. for (double element : a) {
  2371. long bits = Double.doubleToLongBits(element);
  2372. result = 31 * result + (int)(bits ^ (bits >>> 32));
  2373. }
  2374. return result;
  2375. }
  2376. /**
  2377. * Returns a hash code based on the contents of the specified array. If
  2378. * the array contains other arrays as elements, the hash code is based on
  2379. * their identities rather than their contents. It is therefore
  2380. * acceptable to invoke this method on an array that contains itself as an
  2381. * element, either directly or indirectly through one or more levels of
  2382. * arrays.
  2383. *
  2384. * <p>For any two arrays <tt>a</tt> and <tt>b</tt> such that
  2385. * <tt>Arrays.equals(a, b)</tt>, it is also the case that
  2386. * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
  2387. *
  2388. * <p>The value returned by this method is equal to the value that would
  2389. * be returned by <tt>Arrays.asList(a).hashCode()</tt>, unless <tt>a</tt>
  2390. * is <tt>null</tt>, in which case <tt>0</tt> is returned.
  2391. *
  2392. * @param a the array whose content-based hash code to compute
  2393. * @return a content-based hash code for <tt>a</tt>
  2394. * @see #deepHashCode(Object[])
  2395. * @since 1.5
  2396. */
  2397. public static int hashCode(Object a[]) {
  2398. if (a == null)
  2399. return 0;
  2400. int result = 1;
  2401. for (Object element : a)
  2402. result = 31 * result + (element == null ? 0 : element.hashCode());
  2403. return result;
  2404. }
  2405. /**
  2406. * Returns a hash code based on the "deep contents" of the specified
  2407. * array. If the array contains other arrays as elements, the
  2408. * hash code is based on their contents and so on, ad infinitum.
  2409. * It is therefore unacceptable to invoke this method on an array that
  2410. * contains itself as an element, either directly or indirectly through
  2411. * one or more levels of arrays. The behavior of such an invocation is
  2412. * undefined.
  2413. *
  2414. * <p>For any two arrays <tt>a</tt> and <tt>b</tt> such that
  2415. * <tt>Arrays.deepEquals(a, b)</tt>, it is also the case that
  2416. * <tt>Arrays.deepHashCode(a) == Arrays.deepHashCode(b)</tt>.
  2417. *
  2418. * <p>The computation of the value returned by this method is similar to
  2419. * that of the value returned by {@link List#hashCode()} on a list
  2420. * containing the same elements as <tt>a</tt> in the same order, with one
  2421. * difference: If an element <tt>e</tt> of <tt>a</tt> is itself an array,
  2422. * its hash code is computed not by calling <tt>e.hashCode()</tt>, but as
  2423. * by calling the appropriate overloading of <tt>Arrays.hashCode(e)</tt>
  2424. * if <tt>e</tt> is an array of a primitive type, or as by calling
  2425. * <tt>Arrays.deepHashCode(e)</tt> recursively if <tt>e</tt> is an array
  2426. * of a reference type. If <tt>a</tt> is <tt>null</tt>, this method
  2427. * returns 0.
  2428. *
  2429. * @param a the array whose deep-content-based hash code to compute
  2430. * @return a deep-content-based hash code for <tt>a</tt>
  2431. * @see #hashCode(Object[])
  2432. * @since 1.5
  2433. */
  2434. public static int deepHashCode(Object a[]) {
  2435. if (a == null)
  2436. return 0;
  2437. int result = 1;
  2438. for (Object element : a) {
  2439. int elementHash = 0;
  2440. if (element instanceof Object[])
  2441. elementHash = deepHashCode((Object[]) element);
  2442. else if (element instanceof byte[])
  2443. elementHash = hashCode((byte[]) element);
  2444. else if (element instanceof short[])
  2445. elementHash = hashCode((short[]) element);
  2446. else if (element instanceof int[])
  2447. elementHash = hashCode((int[]) element);
  2448. else if (element instanceof long[])
  2449. elementHash = hashCode((long[]) element);
  2450. else if (element instanceof char[])
  2451. elementHash = hashCode((char[]) element);
  2452. else if (element instanceof float[])
  2453. elementHash = hashCode((float[]) element);
  2454. else if (element instanceof double[])
  2455. elementHash = hashCode((double[]) element);
  2456. else if (element instanceof boolean[])
  2457. elementHash = hashCode((boolean[]) element);
  2458. else if (element != null)
  2459. elementHash = element.hashCode();
  2460. result = 31 * result + elementHash;
  2461. }
  2462. return result;
  2463. }
  2464. /**
  2465. * Returns <tt>true</tt> if the two specified arrays are <i>deeply
  2466. * equal</i> to one another. Unlike the @link{#equals{Object[],Object[])
  2467. * method, this method is appropriate for use with nested arrays of
  2468. * arbitrary depth.
  2469. *
  2470. * <p>Two array references are considered deeply equal if both
  2471. * are <tt>null</tt>, or if they refer to arrays that contain the same
  2472. * number of elements and all corresponding pairs of elements in the two
  2473. * arrays are deeply equal.
  2474. *
  2475. * <p>Two possibly <tt>null</tt> elements <tt>e1</tt> and <tt>e2</tt> are
  2476. * deeply equal if any of the following conditions hold:
  2477. * <ul>
  2478. * <li> <tt>e1</tt> and <tt>e2</tt> are both arrays of object reference
  2479. * types, and <tt>Arrays.deepEquals(e1, e2) would return true</tt>
  2480. * <li> <tt>e1</tt> and <tt>e2</tt> are arrays of the same primitive
  2481. * type, and the appropriate overloading of
  2482. * <tt>Arrays.equals(e1, e2)</tt> would return true.
  2483. * <li> <tt>e1 == e2</tt>
  2484. * <li> <tt>e1.equals(e2)</tt> would return true.
  2485. * </ul>
  2486. * Note that this definition permits <tt>null</tt> elements at any depth.
  2487. *
  2488. * <p>If either of the specified arrays contain themselves as elements
  2489. * either directly or indirectly through one or more levels of arrays,
  2490. * the behavior of this method is undefined.
  2491. *
  2492. * @param a1 one array to be tested for equality
  2493. * @param a2 the other array to be tested for equality
  2494. * @return <tt>true</tt> if the two arrays are equal
  2495. * @see #equals(Object[],Object[])
  2496. * @since 1.5
  2497. */
  2498. public static boolean deepEquals(Object[] a1, Object[] a2) {
  2499. if (a1 == a2)
  2500. return true;
  2501. if (a1 == null || a2==null)
  2502. return false;
  2503. int length = a1.length;
  2504. if (a2.length != length)
  2505. return false;
  2506. for (int i = 0; i < length; i++) {
  2507. Object e1 = a1[i];
  2508. Object e2 = a2[i];
  2509. if (e1 == e2)
  2510. continue;
  2511. if (e1 == null)
  2512. return false;
  2513. // Figure out whether the two elements are equal
  2514. boolean eq;
  2515. if (e1 instanceof Object[] && e2 instanceof Object[])
  2516. eq = deepEquals ((Object[]) e1, (Object[]) e2);
  2517. else if (e1 instanceof byte[] && e2 instanceof byte[])
  2518. eq = equals((byte[]) e1, (byte[]) e2);
  2519. else if (e1 instanceof short[] && e2 instanceof short[])
  2520. eq = equals((short[]) e1, (short[]) e2);
  2521. else if (e1 instanceof int[] && e2 instanceof int[])
  2522. eq = equals((int[]) e1, (int[]) e2);
  2523. else if (e1 instanceof long[] && e2 instanceof long[])
  2524. eq = equals((long[]) e1, (long[]) e2);
  2525. else if (e1 instanceof char[] && e2 instanceof char[])
  2526. eq = equals((char[]) e1, (char[]) e2);
  2527. else if (e1 instanceof float[] && e2 instanceof float[])
  2528. eq = equals((float[]) e1, (float[]) e2);
  2529. else if (e1 instanceof double[] && e2 instanceof double[])
  2530. eq = equals((double[]) e1, (double[]) e2);
  2531. else if (e1 instanceof boolean[] && e2 instanceof boolean[])
  2532. eq = equals((boolean[]) e1, (boolean[]) e2);
  2533. else
  2534. eq = e1.equals(e2);
  2535. if (!eq)
  2536. return false;
  2537. }
  2538. return true;
  2539. }
  2540. /**
  2541. * Returns a string representation of the contents of the specified array.
  2542. * The string representation consists of a list of the array's elements,
  2543. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2544. * separated by the characters <tt>", "</tt> (a comma followed by a
  2545. * space). Elements are converted to strings as by
  2546. * <tt>String.valueOf(long)</tt>. Returns <tt>"null"</tt> if <tt>a</tt>
  2547. * is <tt>null</tt>.
  2548. *
  2549. * @param a the array whose string representation to return
  2550. * @return a string representation of <tt>a</tt>
  2551. * @since 1.5
  2552. */
  2553. public static String toString(long[] a) {
  2554. if (a == null)
  2555. return "null";
  2556. if (a.length == 0)
  2557. return "[]";
  2558. StringBuilder buf = new StringBuilder();
  2559. buf.append('[');
  2560. buf.append(a[0]);
  2561. for (int i = 1; i < a.length; i++) {
  2562. buf.append(", ");
  2563. buf.append(a[i]);
  2564. }
  2565. buf.append("]");
  2566. return buf.toString();
  2567. }
  2568. /**
  2569. * Returns a string representation of the contents of the specified array.
  2570. * The string representation consists of a list of the array's elements,
  2571. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2572. * separated by the characters <tt>", "</tt> (a comma followed by a
  2573. * space). Elements are converted to strings as by
  2574. * <tt>String.valueOf(int)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> is
  2575. * <tt>null</tt>.
  2576. *
  2577. * @param a the array whose string representation to return
  2578. * @return a string representation of <tt>a</tt>
  2579. * @since 1.5
  2580. */
  2581. public static String toString(int[] a) {
  2582. if (a == null)
  2583. return "null";
  2584. if (a.length == 0)
  2585. return "[]";
  2586. StringBuilder buf = new StringBuilder();
  2587. buf.append('[');
  2588. buf.append(a[0]);
  2589. for (int i = 1; i < a.length; i++) {
  2590. buf.append(", ");
  2591. buf.append(a[i]);
  2592. }
  2593. buf.append("]");
  2594. return buf.toString();
  2595. }
  2596. /**
  2597. * Returns a string representation of the contents of the specified array.
  2598. * The string representation consists of a list of the array's elements,
  2599. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2600. * separated by the characters <tt>", "</tt> (a comma followed by a
  2601. * space). Elements are converted to strings as by
  2602. * <tt>String.valueOf(short)</tt>. Returns <tt>"null"</tt> if <tt>a</tt>
  2603. * is <tt>null</tt>.
  2604. *
  2605. * @param a the array whose string representation to return
  2606. * @return a string representation of <tt>a</tt>
  2607. * @since 1.5
  2608. */
  2609. public static String toString(short[] a) {
  2610. if (a == null)
  2611. return "null";
  2612. if (a.length == 0)
  2613. return "[]";
  2614. StringBuilder buf = new StringBuilder();
  2615. buf.append('[');
  2616. buf.append(a[0]);
  2617. for (int i = 1; i < a.length; i++) {
  2618. buf.append(", ");
  2619. buf.append(a[i]);
  2620. }
  2621. buf.append("]");
  2622. return buf.toString();
  2623. }
  2624. /**
  2625. * Returns a string representation of the contents of the specified array.
  2626. * The string representation consists of a list of the array's elements,
  2627. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2628. * separated by the characters <tt>", "</tt> (a comma followed by a
  2629. * space). Elements are converted to strings as by
  2630. * <tt>String.valueOf(char)</tt>. Returns <tt>"null"</tt> if <tt>a</tt>
  2631. * is <tt>null</tt>.
  2632. *
  2633. * @param a the array whose string representation to return
  2634. * @return a string representation of <tt>a</tt>
  2635. * @since 1.5
  2636. */
  2637. public static String toString(char[] a) {
  2638. if (a == null)
  2639. return "null";
  2640. if (a.length == 0)
  2641. return "[]";
  2642. StringBuilder buf = new StringBuilder();
  2643. buf.append('[');
  2644. buf.append(a[0]);
  2645. for (int i = 1; i < a.length; i++) {
  2646. buf.append(", ");
  2647. buf.append(a[i]);
  2648. }
  2649. buf.append("]");
  2650. return buf.toString();
  2651. }
  2652. /**
  2653. * Returns a string representation of the contents of the specified array.
  2654. * The string representation consists of a list of the array's elements,
  2655. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements
  2656. * are separated by the characters <tt>", "</tt> (a comma followed
  2657. * by a space). Elements are converted to strings as by
  2658. * <tt>String.valueOf(byte)</tt>. Returns <tt>"null"</tt> if
  2659. * <tt>a</tt> is <tt>null</tt>.
  2660. *
  2661. * @param a the array whose string representation to return
  2662. * @return a string representation of <tt>a</tt>
  2663. * @since 1.5
  2664. */
  2665. public static String toString(byte[] a) {
  2666. if (a == null)
  2667. return "null";
  2668. if (a.length == 0)
  2669. return "[]";
  2670. StringBuilder buf = new StringBuilder();
  2671. buf.append('[');
  2672. buf.append(a[0]);
  2673. for (int i = 1; i < a.length; i++) {
  2674. buf.append(", ");
  2675. buf.append(a[i]);
  2676. }
  2677. buf.append("]");
  2678. return buf.toString();
  2679. }
  2680. /**
  2681. * Returns a string representation of the contents of the specified array.
  2682. * The string representation consists of a list of the array's elements,
  2683. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2684. * separated by the characters <tt>", "</tt> (a comma followed by a
  2685. * space). Elements are converted to strings as by
  2686. * <tt>String.valueOf(boolean)</tt>. Returns <tt>"null"</tt> if
  2687. * <tt>a</tt> is <tt>null</tt>.
  2688. *
  2689. * @param a the array whose string representation to return
  2690. * @return a string representation of <tt>a</tt>
  2691. * @since 1.5
  2692. */
  2693. public static String toString(boolean[] a) {
  2694. if (a == null)
  2695. return "null";
  2696. if (a.length == 0)
  2697. return "[]";
  2698. StringBuilder buf = new StringBuilder();
  2699. buf.append('[');
  2700. buf.append(a[0]);
  2701. for (int i = 1; i < a.length; i++) {
  2702. buf.append(", ");
  2703. buf.append(a[i]);
  2704. }
  2705. buf.append("]");
  2706. return buf.toString();
  2707. }
  2708. /**
  2709. * Returns a string representation of the contents of the specified array.
  2710. * The string representation consists of a list of the array's elements,
  2711. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2712. * separated by the characters <tt>", "</tt> (a comma followed by a
  2713. * space). Elements are converted to strings as by
  2714. * <tt>String.valueOf(float)</tt>. Returns <tt>"null"</tt> if <tt>a</tt>
  2715. * is <tt>null</tt>.
  2716. *
  2717. * @param a the array whose string representation to return
  2718. * @return a string representation of <tt>a</tt>
  2719. * @since 1.5
  2720. */
  2721. public static String toString(float[] a) {
  2722. if (a == null)
  2723. return "null";
  2724. if (a.length == 0)
  2725. return "[]";
  2726. StringBuilder buf = new StringBuilder();
  2727. buf.append('[');
  2728. buf.append(a[0]);
  2729. for (int i = 1; i < a.length; i++) {
  2730. buf.append(", ");
  2731. buf.append(a[i]);
  2732. }
  2733. buf.append("]");
  2734. return buf.toString();
  2735. }
  2736. /**
  2737. * Returns a string representation of the contents of the specified array.
  2738. * The string representation consists of a list of the array's elements,
  2739. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  2740. * separated by the characters <tt>", "</tt> (a comma followed by a
  2741. * space). Elements are converted to strings as by
  2742. * <tt>String.valueOf(double)</tt>. Returns <tt>"null"</tt> if <tt>a</tt>
  2743. * is <tt>null</tt>.
  2744. *
  2745. * @param a the array whose string representation to return
  2746. * @return a string representation of <tt>a</tt>
  2747. * @since 1.5
  2748. */
  2749. public static String toString(double[] a) {
  2750. if (a == null)
  2751. return "null";
  2752. if (a.length == 0)
  2753. return "[]";
  2754. StringBuilder buf = new StringBuilder();
  2755. buf.append('[');
  2756. buf.append(a[0]);
  2757. for (int i = 1; i < a.length; i++) {
  2758. buf.append(", ");
  2759. buf.append(a[i]);
  2760. }
  2761. buf.append("]");
  2762. return buf.toString();
  2763. }
  2764. /**
  2765. * Returns a string representation of the contents of the specified array.
  2766. * If the array contains other arrays as elements, they are converted to
  2767. * strings by the {@link Object#toString} method inherited from
  2768. * <tt>Object</tt>, which describes their <i>identities</i> rather than
  2769. * their contents.
  2770. *
  2771. * <p>The value returned by this method is equal to the value that would
  2772. * be returned by <tt>Arrays.asList(a).toString()</tt>, unless <tt>a</tt>
  2773. * is <tt>null</tt>, in which case <tt>"null"</tt> is returned.
  2774. *
  2775. * @param a the array whose string representation to return
  2776. * @return a string representation of <tt>a</tt>
  2777. * @see #deepToString(Object[])
  2778. * @since 1.5
  2779. */
  2780. public static String toString(Object[] a) {
  2781. if (a == null)
  2782. return "null";
  2783. if (a.length == 0)
  2784. return "[]";
  2785. StringBuilder buf = new StringBuilder();
  2786. for (int i = 0; i < a.length; i++) {
  2787. if (i == 0)
  2788. buf.append('[');
  2789. else
  2790. buf.append(", ");
  2791. buf.append(String.valueOf(a[i]));
  2792. }
  2793. buf.append("]");
  2794. return buf.toString();
  2795. }
  2796. /**
  2797. * Returns a string representation of the "deep contents" of the specified
  2798. * array. If the array contains other arrays as elements, the string
  2799. * representation contains their contents and so on. This method is
  2800. * designed for converting multidimensional arrays to strings.
  2801. *
  2802. * <p>The string representation consists of a list of the array's
  2803. * elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent
  2804. * elements are separated by the characters <tt>", "</tt> (a comma
  2805. * followed by a space). Elements are converted to strings as by
  2806. * <tt>String.valueOf(Object)</tt>, unless they are themselves
  2807. * arrays.
  2808. *
  2809. * <p>If an element <tt>e</tt> is an array of a primitive type, it is
  2810. * converted to a string as by invoking the appropriate overloading of
  2811. * <tt>Arrays.toString(e)</tt>. If an element <tt>e</tt> is an array of a
  2812. * reference type, it is converted to a string as by invoking
  2813. * this method recursively.
  2814. *
  2815. * <p>To avoid infinite recursion, if the specified array contains itself
  2816. * as an element, or contains an indirect reference to itself through one
  2817. * or more levels of arrays, the self-reference is converted to the string
  2818. * <tt>"[...]"</tt>. For example, an array containing only a reference
  2819. * to itself would be rendered as <tt>"[[...]]"</tt>.
  2820. *
  2821. * <p>This method returns <tt>"null"</tt> if the specified array
  2822. * is <tt>null</tt>.
  2823. *
  2824. * @param a the array whose string representation to return
  2825. * @return a string representation of <tt>a</tt>
  2826. * @see #toString(Object[])
  2827. * @since 1.5
  2828. */
  2829. public static String deepToString(Object[] a) {
  2830. if (a == null)
  2831. return "null";
  2832. int bufLen = 20 * a.length;
  2833. if (a.length != 0 && bufLen <= 0)
  2834. bufLen = Integer.MAX_VALUE;
  2835. StringBuilder buf = new StringBuilder(bufLen);
  2836. deepToString(a, buf, new HashSet());
  2837. return buf.toString();
  2838. }
  2839. private static void deepToString(Object[] a, StringBuilder buf,
  2840. Set<Object[]> dejaVu) {
  2841. if (a == null) {
  2842. buf.append("null");
  2843. return;
  2844. }
  2845. dejaVu.add(a);
  2846. buf.append('[');
  2847. for (int i = 0; i < a.length; i++) {
  2848. if (i != 0)
  2849. buf.append(", ");
  2850. Object element = a[i];
  2851. if (element == null) {
  2852. buf.append("null");
  2853. } else {
  2854. Class eClass = element.getClass();
  2855. if (eClass.isArray()) {
  2856. if (eClass == byte[].class)
  2857. buf.append(toString((byte[]) element));
  2858. else if (eClass == short[].class)
  2859. buf.append(toString((short[]) element));
  2860. else if (eClass == int[].class)
  2861. buf.append(toString((int[]) element));
  2862. else if (eClass == long[].class)
  2863. buf.append(toString((long[]) element));
  2864. else if (eClass == char[].class)
  2865. buf.append(toString((char[]) element));
  2866. else if (eClass == float[].class)
  2867. buf.append(toString((float[]) element));
  2868. else if (eClass == double[].class)
  2869. buf.append(toString((double[]) element));
  2870. else if (eClass == boolean[].class)
  2871. buf.append(toString((boolean[]) element));
  2872. else { // element is an array of object references
  2873. if (dejaVu.contains(element))
  2874. buf.append("[...]");
  2875. else
  2876. deepToString((Object[])element, buf, dejaVu);
  2877. }
  2878. } else { // element is non-null and not an array
  2879. buf.append(element.toString());
  2880. }
  2881. }
  2882. }
  2883. buf.append("]");
  2884. dejaVu.remove(a);
  2885. }
  2886. }