1. /*
  2. * @(#)Collections.java 1.66 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util;
  8. import java.io.Serializable;
  9. /**
  10. * This class consists exclusively of static methods that operate on or return
  11. * collections. It contains polymorphic algorithms that operate on
  12. * collections, "wrappers", which return a new collection backed by a
  13. * specified collection, and a few other odds and ends.
  14. *
  15. * <p>The methods of this class all throw a <tt>NullPointerException</tt>
  16. * if the collections provided to them are null.
  17. *
  18. * <p>The documentation for the polymorphic algorithms contained in this class
  19. * generally includes a brief description of the <i>implementation</i>. Such
  20. * descriptions should be regarded as <i>implementation notes</i>, rather than
  21. * parts of the <i>specification</i>. Implementors should feel free to
  22. * substitute other algorithms, so long as the specification itself is adhered
  23. * to. (For example, the algorithm used by <tt>sort</tt> does not have to be
  24. * a mergesort, but it does have to be <i>stable</i>.)
  25. *
  26. * <p>The "destructive" algorithms contained in this class, that is, the
  27. * algorithms that modify the collection on which they operate, are specified
  28. * to throw <tt>UnsupportedOperationException</tt> if the collection does not
  29. * support the appropriate mutation primitive(s), such as the <tt>set</tt>
  30. * method. These algorithms may, but are not required to, throw this
  31. * exception if an invocation would have no effect on the collection. For
  32. * example, invoking the <tt>sort</tt> method on an unmodifiable list that is
  33. * already sorted may or may not throw <tt>UnsupportedOperationException</tt>.
  34. *
  35. * <p>This class is a member of the
  36. * <a href="{@docRoot}/../guide/collections/index.html">
  37. * Java Collections Framework</a>.
  38. *
  39. * @author Josh Bloch
  40. * @version 1.66, 01/23/03
  41. * @see Collection
  42. * @see Set
  43. * @see List
  44. * @see Map
  45. * @since 1.2
  46. */
  47. public class Collections {
  48. // Suppresses default constructor, ensuring non-instantiability.
  49. private Collections() {
  50. }
  51. // Algorithms
  52. /*
  53. * Tuning parameters for algorithms - Many of the List algorithms have
  54. * two implementations, one of which is appropriate for RandomAccess
  55. * lists, the other for "sequential." Often, the random access variant
  56. * yields better performance on small sequential access lists. The
  57. * tuning parameters below determine the cutoff point for what constitutes
  58. * a "small" sequential access list for each algorithm. The values below
  59. * were empirically determined to work well for LinkedList. Hopefully
  60. * they should be reasonable for other sequential access List
  61. * implementations. Those doing performance work on this code would
  62. * do well to validate the values of these parameters from time to time.
  63. * (The first word of each tuning parameter name is the algorithm to which
  64. * it applies.)
  65. */
  66. private static final int BINARYSEARCH_THRESHOLD = 5000;
  67. private static final int REVERSE_THRESHOLD = 18;
  68. private static final int SHUFFLE_THRESHOLD = 5;
  69. private static final int FILL_THRESHOLD = 25;
  70. private static final int ROTATE_THRESHOLD = 100;
  71. private static final int COPY_THRESHOLD = 10;
  72. private static final int REPLACEALL_THRESHOLD = 11;
  73. private static final int INDEXOFSUBLIST_THRESHOLD = 35;
  74. /**
  75. * Sorts the specified list into ascending order, according to the
  76. * <i>natural ordering</i> of its elements. All elements in the list must
  77. * implement the <tt>Comparable</tt> interface. Furthermore, all elements
  78. * in the list must be <i>mutually comparable</i> (that is,
  79. * <tt>e1.compareTo(e2)</tt> must not throw a <tt>ClassCastException</tt>
  80. * for any elements <tt>e1</tt> and <tt>e2</tt> in the list).<p>
  81. *
  82. * This sort is guaranteed to be <i>stable</i>: equal elements will
  83. * not be reordered as a result of the sort.<p>
  84. *
  85. * The specified list must be modifiable, but need not be resizable.<p>
  86. *
  87. * The sorting algorithm is a modified mergesort (in which the merge is
  88. * omitted if the highest element in the low sublist is less than the
  89. * lowest element in the high sublist). This algorithm offers guaranteed
  90. * n log(n) performance.
  91. *
  92. * This implementation dumps the specified list into an array, sorts
  93. * the array, and iterates over the list resetting each element
  94. * from the corresponding position in the array. This avoids the
  95. * n<sup>2</sup> log(n) performance that would result from attempting
  96. * to sort a linked list in place.
  97. *
  98. * @param list the list to be sorted.
  99. * @throws ClassCastException if the list contains elements that are not
  100. * <i>mutually comparable</i> (for example, strings and integers).
  101. * @throws UnsupportedOperationException if the specified list's
  102. * list-iterator does not support the <tt>set</tt> operation.
  103. * @see Comparable
  104. */
  105. public static void sort(List list) {
  106. Object a[] = list.toArray();
  107. Arrays.sort(a);
  108. ListIterator i = list.listIterator();
  109. for (int j=0; j<a.length; j++) {
  110. i.next();
  111. i.set(a[j]);
  112. }
  113. }
  114. /**
  115. * Sorts the specified list according to the order induced by the
  116. * specified comparator. All elements in the list must be <i>mutually
  117. * comparable</i> using the specified comparator (that is,
  118. * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt>
  119. * for any elements <tt>e1</tt> and <tt>e2</tt> in the list).<p>
  120. *
  121. * This sort is guaranteed to be <i>stable</i>: equal elements will
  122. * not be reordered as a result of the sort.<p>
  123. *
  124. * The sorting algorithm is a modified mergesort (in which the merge is
  125. * omitted if the highest element in the low sublist is less than the
  126. * lowest element in the high sublist). This algorithm offers guaranteed
  127. * n log(n) performance.
  128. *
  129. * The specified list must be modifiable, but need not be resizable.
  130. * This implementation dumps the specified list into an array, sorts
  131. * the array, and iterates over the list resetting each element
  132. * from the corresponding position in the array. This avoids the
  133. * n<sup>2</sup> log(n) performance that would result from attempting
  134. * to sort a linked list in place.
  135. *
  136. * @param list the list to be sorted.
  137. * @param c the comparator to determine the order of the list. A
  138. * <tt>null</tt> value indicates that the elements' <i>natural
  139. * ordering</i> should be used.
  140. * @throws ClassCastException if the list contains elements that are not
  141. * <i>mutually comparable</i> using the specified comparator.
  142. * @throws UnsupportedOperationException if the specified list's
  143. * list-iterator does not support the <tt>set</tt> operation.
  144. * @see Comparator
  145. */
  146. public static void sort(List list, Comparator c) {
  147. Object a[] = list.toArray();
  148. Arrays.sort(a, c);
  149. ListIterator i = list.listIterator();
  150. for (int j=0; j<a.length; j++) {
  151. i.next();
  152. i.set(a[j]);
  153. }
  154. }
  155. /**
  156. * Searches the specified list for the specified object using the binary
  157. * search algorithm. The list must be sorted into ascending order
  158. * according to the <i>natural ordering</i> of its elements (as by the
  159. * <tt>sort(List)</tt> method, above) prior to making this call. If it is
  160. * not sorted, the results are undefined. If the list contains multiple
  161. * elements equal to the specified object, there is no guarantee which one
  162. * will be found.<p>
  163. *
  164. * This method runs in log(n) time for a "random access" list (which
  165. * provides near-constant-time positional access). If the specified list
  166. * does not implement the {@link RandomAccess} and is large, this method
  167. * will do an iterator-based binary search that performs O(n) link
  168. * traversals and O(log n) element comparisons.
  169. *
  170. * @param list the list to be searched.
  171. * @param key the key to be searched for.
  172. * @return index of the search key, if it is contained in the list;
  173. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  174. * <i>insertion point</i> is defined as the point at which the
  175. * key would be inserted into the list: the index of the first
  176. * element greater than the key, or <tt>list.size()</tt>, if all
  177. * elements in the list are less than the specified key. Note
  178. * that this guarantees that the return value will be >= 0 if
  179. * and only if the key is found.
  180. * @throws ClassCastException if the list contains elements that are not
  181. * <i>mutually comparable</i> (for example, strings and
  182. * integers), or the search key in not mutually comparable
  183. * with the elements of the list.
  184. * @see Comparable
  185. * @see #sort(List)
  186. */
  187. public static int binarySearch(List list, Object key) {
  188. if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
  189. return indexedBinarySearch(list, key);
  190. else
  191. return iteratorBinarySearch(list, key);
  192. }
  193. private static int indexedBinarySearch(List list, Object key) {
  194. int low = 0;
  195. int high = list.size()-1;
  196. while (low <= high) {
  197. int mid = (low + high) >> 1;
  198. Object midVal = list.get(mid);
  199. int cmp = ((Comparable)midVal).compareTo(key);
  200. if (cmp < 0)
  201. low = mid + 1;
  202. else if (cmp > 0)
  203. high = mid - 1;
  204. else
  205. return mid; // key found
  206. }
  207. return -(low + 1); // key not found
  208. }
  209. private static int iteratorBinarySearch(List list, Object key) {
  210. int low = 0;
  211. int high = list.size()-1;
  212. ListIterator i = list.listIterator();
  213. while (low <= high) {
  214. int mid = (low + high) >> 1;
  215. Object midVal = get(i, mid);
  216. int cmp = ((Comparable)midVal).compareTo(key);
  217. if (cmp < 0)
  218. low = mid + 1;
  219. else if (cmp > 0)
  220. high = mid - 1;
  221. else
  222. return mid; // key found
  223. }
  224. return -(low + 1); // key not found
  225. }
  226. /**
  227. * Gets the ith element from the given list by repositioning the specified
  228. * list listIterator.
  229. */
  230. private static Object get(ListIterator i, int index) {
  231. Object obj = null;
  232. int pos = i.nextIndex();
  233. if (pos <= index) {
  234. do {
  235. obj = i.next();
  236. } while (pos++ < index);
  237. } else {
  238. do {
  239. obj = i.previous();
  240. } while (--pos > index);
  241. }
  242. return obj;
  243. }
  244. /**
  245. * Searches the specified list for the specified object using the binary
  246. * search algorithm. The list must be sorted into ascending order
  247. * according to the specified comparator (as by the <tt>Sort(List,
  248. * Comparator)</tt> method, above), prior to making this call. If it is
  249. * not sorted, the results are undefined. If the list contains multiple
  250. * elements equal to the specified object, there is no guarantee which one
  251. * will be found.<p>
  252. *
  253. * This method runs in log(n) time for a "random access" list (which
  254. * provides near-constant-time positional access). If the specified list
  255. * does not implement the {@link RandomAccess} and is large, this
  256. * this method will do an iterator-based binary search that performs
  257. * O(n) link traversals and O(log n) element comparisons.
  258. *
  259. * @param list the list to be searched.
  260. * @param key the key to be searched for.
  261. * @param c the comparator by which the list is ordered. A
  262. * <tt>null</tt> value indicates that the elements' <i>natural
  263. * ordering</i> should be used.
  264. * @return index of the search key, if it is contained in the list;
  265. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  266. * <i>insertion point</i> is defined as the point at which the
  267. * key would be inserted into the list: the index of the first
  268. * element greater than the key, or <tt>list.size()</tt>, if all
  269. * elements in the list are less than the specified key. Note
  270. * that this guarantees that the return value will be >= 0 if
  271. * and only if the key is found.
  272. * @throws ClassCastException if the list contains elements that are not
  273. * <i>mutually comparable</i> using the specified comparator,
  274. * or the search key in not mutually comparable with the
  275. * elements of the list using this comparator.
  276. * @see Comparable
  277. * @see #sort(List, Comparator)
  278. */
  279. public static int binarySearch(List list, Object key, Comparator c) {
  280. if (c==null)
  281. return binarySearch(list, key);
  282. if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
  283. return indexedBinarySearch(list, key, c);
  284. else
  285. return iteratorBinarySearch(list, key, c);
  286. }
  287. private static int indexedBinarySearch(List l, Object key, Comparator c) {
  288. int low = 0;
  289. int high = l.size()-1;
  290. while (low <= high) {
  291. int mid = (low + high) >> 1;
  292. Object midVal = l.get(mid);
  293. int cmp = c.compare(midVal, key);
  294. if (cmp < 0)
  295. low = mid + 1;
  296. else if (cmp > 0)
  297. high = mid - 1;
  298. else
  299. return mid; // key found
  300. }
  301. return -(low + 1); // key not found
  302. }
  303. private static int iteratorBinarySearch(List l, Object key, Comparator c) {
  304. int low = 0;
  305. int high = l.size()-1;
  306. ListIterator i = l.listIterator();
  307. while (low <= high) {
  308. int mid = (low + high) >> 1;
  309. Object midVal = get(i, mid);
  310. int cmp = c.compare(midVal, key);
  311. if (cmp < 0)
  312. low = mid + 1;
  313. else if (cmp > 0)
  314. high = mid - 1;
  315. else
  316. return mid; // key found
  317. }
  318. return -(low + 1); // key not found
  319. }
  320. /**
  321. * Reverses the order of the elements in the specified list.<p>
  322. *
  323. * This method runs in linear time.
  324. *
  325. * @param list the list whose elements are to be reversed.
  326. * @throws UnsupportedOperationException if the specified list or
  327. * its list-iterator does not support the <tt>set</tt> method.
  328. */
  329. public static void reverse(List list) {
  330. int size = list.size();
  331. if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
  332. for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
  333. swap(list, i, j);
  334. } else {
  335. ListIterator fwd = list.listIterator();
  336. ListIterator rev = list.listIterator(size);
  337. for (int i=0, mid=list.size()>>1; i<mid; i++) {
  338. Object tmp = fwd.next();
  339. fwd.set(rev.previous());
  340. rev.set(tmp);
  341. }
  342. }
  343. }
  344. /**
  345. * Randomly permutes the specified list using a default source of
  346. * randomness. All permutations occur with approximately equal
  347. * likelihood.<p>
  348. *
  349. * The hedge "approximately" is used in the foregoing description because
  350. * default source of randomenss is only approximately an unbiased source
  351. * of independently chosen bits. If it were a perfect source of randomly
  352. * chosen bits, then the algorithm would choose permutations with perfect
  353. * uniformity.<p>
  354. *
  355. * This implementation traverses the list backwards, from the last element
  356. * up to the second, repeatedly swapping a randomly selected element into
  357. * the "current position". Elements are randomly selected from the
  358. * portion of the list that runs from the first element to the current
  359. * position, inclusive.<p>
  360. *
  361. * This method runs in linear time. If the specified list does not
  362. * implement the {@link RandomAccess} interface and is large, this
  363. * implementation dumps the specified list into an array before shuffling
  364. * it, and dumps the shuffled array back into the list. This avoids the
  365. * quadratic behavior that would result from shuffling a "sequential
  366. * access" list in place.
  367. *
  368. * @param list the list to be shuffled.
  369. * @throws UnsupportedOperationException if the specified list or
  370. * its list-iterator does not support the <tt>set</tt> method.
  371. */
  372. public static void shuffle(List list) {
  373. shuffle(list, r);
  374. }
  375. private static Random r = new Random();
  376. /**
  377. * Randomly permute the specified list using the specified source of
  378. * randomness. All permutations occur with equal likelihood
  379. * assuming that the source of randomness is fair.<p>
  380. *
  381. * This implementation traverses the list backwards, from the last element
  382. * up to the second, repeatedly swapping a randomly selected element into
  383. * the "current position". Elements are randomly selected from the
  384. * portion of the list that runs from the first element to the current
  385. * position, inclusive.<p>
  386. *
  387. * This method runs in linear time. If the specified list does not
  388. * implement the {@link RandomAccess} interface and is large, this
  389. * implementation dumps the specified list into an array before shuffling
  390. * it, and dumps the shuffled array back into the list. This avoids the
  391. * quadratic behavior that would result from shuffling a "sequential
  392. * access" list in place.
  393. *
  394. * @param list the list to be shuffled.
  395. * @param rnd the source of randomness to use to shuffle the list.
  396. * @throws UnsupportedOperationException if the specified list or its
  397. * list-iterator does not support the <tt>set</tt> operation.
  398. */
  399. public static void shuffle(List list, Random rnd) {
  400. int size = list.size();
  401. if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
  402. for (int i=size; i>1; i--)
  403. swap(list, i-1, rnd.nextInt(i));
  404. } else {
  405. Object arr[] = list.toArray();
  406. // Shuffle array
  407. for (int i=size; i>1; i--)
  408. swap(arr, i-1, rnd.nextInt(i));
  409. // Dump array back into list
  410. ListIterator it = list.listIterator();
  411. for (int i=0; i<arr.length; i++) {
  412. it.next();
  413. it.set(arr[i]);
  414. }
  415. }
  416. }
  417. /**
  418. * Swaps the elements at the specified positions in the specified list.
  419. * (If the specified positions are equal, invoking this method leaves
  420. * the list unchanged.)
  421. *
  422. * @param list The list in which to swap elements.
  423. * @param i the index of one element to be swapped.
  424. * @param j the index of the other element to be swapped.
  425. * @throws IndexOutOfBoundsException if either <tt>i</tt> or <tt>j</tt>
  426. * is out of range (i < 0 || i >= list.size()
  427. * || j < 0 || j >= list.size()).
  428. * @since 1.4
  429. */
  430. public static void swap(List list, int i, int j) {
  431. list.set(i, list.set(j, list.get(i)));
  432. }
  433. /**
  434. * Swaps the two specified elements in the specified array.
  435. */
  436. private static void swap(Object[] arr, int i, int j) {
  437. Object tmp = arr[i];
  438. arr[i] = arr[j];
  439. arr[j] = tmp;
  440. }
  441. /**
  442. * Replaces all of the elements of the specified list with the specified
  443. * element. <p>
  444. *
  445. * This method runs in linear time.
  446. *
  447. * @param list the list to be filled with the specified element.
  448. * @param obj The element with which to fill the specified list.
  449. * @throws UnsupportedOperationException if the specified list or its
  450. * list-iterator does not support the <tt>set</tt> operation.
  451. */
  452. public static void fill(List list, Object obj) {
  453. int size = list.size();
  454. if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
  455. for (int i=0; i<size; i++)
  456. list.set(i, obj);
  457. } else {
  458. ListIterator itr = list.listIterator();
  459. for (int i=0; i<size; i++) {
  460. itr.next();
  461. itr.set(obj);
  462. }
  463. }
  464. }
  465. /**
  466. * Copies all of the elements from one list into another. After the
  467. * operation, the index of each copied element in the destination list
  468. * will be identical to its index in the source list. The destination
  469. * list must be at least as long as the source list. If it is longer, the
  470. * remaining elements in the destination list are unaffected. <p>
  471. *
  472. * This method runs in linear time.
  473. *
  474. * @param dest The destination list.
  475. * @param src The source list.
  476. * @throws IndexOutOfBoundsException if the destination list is too small
  477. * to contain the entire source List.
  478. * @throws UnsupportedOperationException if the destination list's
  479. * list-iterator does not support the <tt>set</tt> operation.
  480. */
  481. public static void copy(List dest, List src) {
  482. int srcSize = src.size();
  483. if (srcSize > dest.size())
  484. throw new IndexOutOfBoundsException("Source does not fit in dest");
  485. if (srcSize < COPY_THRESHOLD ||
  486. (src instanceof RandomAccess && dest instanceof RandomAccess)) {
  487. for (int i=0; i<srcSize; i++)
  488. dest.set(i, src.get(i));
  489. } else {
  490. ListIterator di=dest.listIterator(), si=src.listIterator();
  491. for (int i=0; i<srcSize; i++) {
  492. di.next();
  493. di.set(si.next());
  494. }
  495. }
  496. }
  497. /**
  498. * Returns the minimum element of the given collection, according to the
  499. * <i>natural ordering</i> of its elements. All elements in the
  500. * collection must implement the <tt>Comparable</tt> interface.
  501. * Furthermore, all elements in the collection must be <i>mutually
  502. * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  503. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  504. * <tt>e2</tt> in the collection).<p>
  505. *
  506. * This method iterates over the entire collection, hence it requires
  507. * time proportional to the size of the collection.
  508. *
  509. * @param coll the collection whose minimum element is to be determined.
  510. * @return the minimum element of the given collection, according
  511. * to the <i>natural ordering</i> of its elements.
  512. * @throws ClassCastException if the collection contains elements that are
  513. * not <i>mutually comparable</i> (for example, strings and
  514. * integers).
  515. * @throws NoSuchElementException if the collection is empty.
  516. * @see Comparable
  517. */
  518. public static Object min(Collection coll) {
  519. Iterator i = coll.iterator();
  520. Comparable candidate = (Comparable)(i.next());
  521. while(i.hasNext()) {
  522. Comparable next = (Comparable)(i.next());
  523. if (next.compareTo(candidate) < 0)
  524. candidate = next;
  525. }
  526. return candidate;
  527. }
  528. /**
  529. * Returns the minimum element of the given collection, according to the
  530. * order induced by the specified comparator. All elements in the
  531. * collection must be <i>mutually comparable</i> by the specified
  532. * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
  533. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  534. * <tt>e2</tt> in the collection).<p>
  535. *
  536. * This method iterates over the entire collection, hence it requires
  537. * time proportional to the size of the collection.
  538. *
  539. * @param coll the collection whose minimum element is to be determined.
  540. * @param comp the comparator with which to determine the minimum element.
  541. * A <tt>null</tt> value indicates that the elements' <i>natural
  542. * ordering</i> should be used.
  543. * @return the minimum element of the given collection, according
  544. * to the specified comparator.
  545. * @throws ClassCastException if the collection contains elements that are
  546. * not <i>mutually comparable</i> using the specified comparator.
  547. * @throws NoSuchElementException if the collection is empty.
  548. * @see Comparable
  549. */
  550. public static Object min(Collection coll, Comparator comp) {
  551. if (comp==null)
  552. return min(coll);
  553. Iterator i = coll.iterator();
  554. Object candidate = i.next();
  555. while(i.hasNext()) {
  556. Object next = i.next();
  557. if (comp.compare(next, candidate) < 0)
  558. candidate = next;
  559. }
  560. return candidate;
  561. }
  562. /**
  563. * Returns the maximum element of the given collection, according to the
  564. * <i>natural ordering</i> of its elements. All elements in the
  565. * collection must implement the <tt>Comparable</tt> interface.
  566. * Furthermore, all elements in the collection must be <i>mutually
  567. * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  568. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  569. * <tt>e2</tt> in the collection).<p>
  570. *
  571. * This method iterates over the entire collection, hence it requires
  572. * time proportional to the size of the collection.
  573. *
  574. * @param coll the collection whose maximum element is to be determined.
  575. * @return the maximum element of the given collection, according
  576. * to the <i>natural ordering</i> of its elements.
  577. * @throws ClassCastException if the collection contains elements that are
  578. * not <i>mutually comparable</i> (for example, strings and
  579. * integers).
  580. * @throws NoSuchElementException if the collection is empty.
  581. * @see Comparable
  582. */
  583. public static Object max(Collection coll) {
  584. Iterator i = coll.iterator();
  585. Comparable candidate = (Comparable)(i.next());
  586. while(i.hasNext()) {
  587. Comparable next = (Comparable)(i.next());
  588. if (next.compareTo(candidate) > 0)
  589. candidate = next;
  590. }
  591. return candidate;
  592. }
  593. /**
  594. * Returns the maximum element of the given collection, according to the
  595. * order induced by the specified comparator. All elements in the
  596. * collection must be <i>mutually comparable</i> by the specified
  597. * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
  598. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  599. * <tt>e2</tt> in the collection).<p>
  600. *
  601. * This method iterates over the entire collection, hence it requires
  602. * time proportional to the size of the collection.
  603. *
  604. * @param coll the collection whose maximum element is to be determined.
  605. * @param comp the comparator with which to determine the maximum element.
  606. * A <tt>null</tt> value indicates that the elements' <i>natural
  607. * ordering</i> should be used.
  608. * @return the maximum element of the given collection, according
  609. * to the specified comparator.
  610. * @throws ClassCastException if the collection contains elements that are
  611. * not <i>mutually comparable</i> using the specified comparator.
  612. * @throws NoSuchElementException if the collection is empty.
  613. * @see Comparable
  614. */
  615. public static Object max(Collection coll, Comparator comp) {
  616. if (comp==null)
  617. return max(coll);
  618. Iterator i = coll.iterator();
  619. Object candidate = i.next();
  620. while(i.hasNext()) {
  621. Object next = i.next();
  622. if (comp.compare(next, candidate) > 0)
  623. candidate = next;
  624. }
  625. return candidate;
  626. }
  627. /**
  628. * Rotates the elements in the specified list by the specified distance.
  629. * After calling this method, the element at index <tt>i</tt> will be
  630. * the element previously at index <tt>(i - distance)</tt> mod
  631. * <tt>list.size()</tt>, for all values of <tt>i</tt> between <tt>0</tt>
  632. * and <tt>list.size()-1</tt>, inclusive. (This method has no effect on
  633. * the size of the list.)
  634. *
  635. * <p>For example, suppose <tt>list</tt> comprises<tt> [t, a, n, k, s]</tt>.
  636. * After invoking <tt>Collections.rotate(list, 1)</tt> (or
  637. * <tt>Collections.rotate(list, -4)</tt>), <tt>list</tt> will comprise
  638. * <tt>[s, t, a, n, k]</tt>.
  639. *
  640. * <p>Note that this method can usefully be applied to sublists to
  641. * move one or more elements within a list while preserving the
  642. * order of the remaining elements. For example, the following idiom
  643. * moves the element at index <tt>j</tt> forward to position
  644. * <tt>k</tt> (which must be greater than or equal to <tt>j</tt>):
  645. * <pre>
  646. * Collections.rotate(list.subList(j, k+1), -1);
  647. * </pre>
  648. * To make this concrete, suppose <tt>list</tt> comprises
  649. * <tt>[a, b, c, d, e]</tt>. To move the element at index <tt>1</tt>
  650. * (<tt>b</tt>) forward two positions, perform the following invocation:
  651. * <pre>
  652. * Collections.rotate(l.subList(1, 4), -1);
  653. * </pre>
  654. * The resulting list is <tt>[a, c, d, b, e]</tt>.
  655. *
  656. * <p>To move more than one element forward, increase the absolute value
  657. * of the rotation distance. To move elements backward, use a positive
  658. * shift distance.
  659. *
  660. * <p>If the specified list is small or implements the {@link
  661. * RandomAccess} interface, this implementation exchanges the first
  662. * element into the location it should go, and then repeatedly exchanges
  663. * the displaced element into the location it should go until a displaced
  664. * element is swapped into the first element. If necessary, the process
  665. * is repeated on the second and successive elements, until the rotation
  666. * is complete. If the specified list is large and doesn't implement the
  667. * <tt>RandomAccess</tt> interface, this implementation breaks the
  668. * list into two sublist views around index <tt>-distance mod size</tt>.
  669. * Then the {@link #reverse(List)} method is invoked on each sublist view,
  670. * and finally it is invoked on the entire list. For a more complete
  671. * description of both algorithms, see Section 2.3 of Jon Bentley's
  672. * <i>Programming Pearls</i> (Addison-Wesley, 1986).
  673. *
  674. * @param list the list to be rotated.
  675. * @param distance the distance to rotate the list. There are no
  676. * constraints on this value; it may be zero, negative, or
  677. * greater than <tt>list.size()</tt>.
  678. * @throws UnsupportedOperationException if the specified list or
  679. * its list-iterator does not support the <tt>set</tt> method.
  680. * @since 1.4
  681. */
  682. public static void rotate(List list, int distance) {
  683. if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
  684. rotate1(list, distance);
  685. else
  686. rotate2(list, distance);
  687. }
  688. private static void rotate1(List list, int distance) {
  689. int size = list.size();
  690. if (size == 0)
  691. return;
  692. distance = distance % size;
  693. if (distance < 0)
  694. distance += size;
  695. if (distance == 0)
  696. return;
  697. for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
  698. Object displaced = list.get(cycleStart);
  699. int i = cycleStart;
  700. do {
  701. i += distance;
  702. if (i >= size)
  703. i -= size;
  704. displaced = list.set(i, displaced);
  705. nMoved ++;
  706. } while(i != cycleStart);
  707. }
  708. }
  709. private static void rotate2(List list, int distance) {
  710. int size = list.size();
  711. if (size == 0)
  712. return;
  713. int mid = -distance % size;
  714. if (mid < 0)
  715. mid += size;
  716. if (mid == 0)
  717. return;
  718. Collections.reverse(list.subList(0, mid));
  719. Collections.reverse(list.subList(mid, size));
  720. Collections.reverse(list);
  721. }
  722. /**
  723. * Replaces all occurrences of one specified value in a list with another.
  724. * More formally, replaces with <tt>newVal</tt> each element <tt>e</tt>
  725. * in <tt>list</tt> such that
  726. * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>.
  727. * (This method has no effect on the size of the list.)
  728. *
  729. * @param list the list in which replacement is to occur.
  730. * @param oldVal the old value to be replaced.
  731. * @param newVal the new value with which <tt>oldVal</tt> is to be
  732. * replaced.
  733. * @return <tt>true</tt> if <tt>list</tt> contained one or more elements
  734. * <tt>e</tt> such that
  735. * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>.
  736. * @throws UnsupportedOperationException if the specified list or
  737. * its list-iterator does not support the <tt>set</tt> method.
  738. * @since 1.4
  739. */
  740. public static boolean replaceAll(List list, Object oldVal, Object newVal) {
  741. boolean result = false;
  742. int size = list.size();
  743. if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) {
  744. if (oldVal==null) {
  745. for (int i=0; i<size; i++) {
  746. if (list.get(i)==null) {
  747. list.set(i, newVal);
  748. result = true;
  749. }
  750. }
  751. } else {
  752. for (int i=0; i<size; i++) {
  753. if (oldVal.equals(list.get(i))) {
  754. list.set(i, newVal);
  755. result = true;
  756. }
  757. }
  758. }
  759. } else {
  760. ListIterator itr=list.listIterator();
  761. if (oldVal==null) {
  762. for (int i=0; i<size; i++) {
  763. if (itr.next()==null) {
  764. itr.set(newVal);
  765. result = true;
  766. }
  767. }
  768. } else {
  769. for (int i=0; i<size; i++) {
  770. if (oldVal.equals(itr.next())) {
  771. itr.set(newVal);
  772. result = true;
  773. }
  774. }
  775. }
  776. }
  777. return result;
  778. }
  779. /**
  780. * Returns the starting position of the first occurrence of the specified
  781. * target list within the specified source list, or -1 if there is no
  782. * such occurrence. More formally, returns the the lowest index <tt>i</tt>
  783. * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>,
  784. * or -1 if there is no such index. (Returns -1 if
  785. * <tt>target.size() > source.size()</tt>.)
  786. *
  787. * <p>This implementation uses the "brute force" technique of scanning
  788. * over the source list, looking for a match with the target at each
  789. * location in turn.
  790. *
  791. * @param source the list in which to search for the first occurrence
  792. * of <tt>target</tt>.
  793. * @param target the list to search for as a subList of <tt>source</tt>.
  794. * @return the starting position of the first occurrence of the specified
  795. * target list within the specified source list, or -1 if there
  796. * is no such occurrence.
  797. * @since 1.4
  798. */
  799. public static int indexOfSubList(List source, List target) {
  800. int sourceSize = source.size();
  801. int targetSize = target.size();
  802. int maxCandidate = sourceSize - targetSize;
  803. if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
  804. (source instanceof RandomAccess&&target instanceof RandomAccess)) {
  805. nextCand:
  806. for (int candidate = 0; candidate <= maxCandidate; candidate++) {
  807. for (int i=0, j=candidate; i<targetSize; i++, j++)
  808. if (!eq(target.get(i), source.get(j)))
  809. continue nextCand; // Element mismatch, try next cand
  810. return candidate; // All elements of candidate matched target
  811. }
  812. } else { // Iterator version of above algorithm
  813. ListIterator si = source.listIterator();
  814. nextCand:
  815. for (int candidate = 0; candidate <= maxCandidate; candidate++) {
  816. ListIterator ti = target.listIterator();
  817. for (int i=0; i<targetSize; i++) {
  818. if (!eq(ti.next(), si.next())) {
  819. // Back up source iterator to next candidate
  820. for (int j=0; j<i; j++)
  821. si.previous();
  822. continue nextCand;
  823. }
  824. }
  825. return candidate;
  826. }
  827. }
  828. return -1; // No candidate matched the target
  829. }
  830. /**
  831. * Returns the starting position of the last occurrence of the specified
  832. * target list within the specified source list, or -1 if there is no such
  833. * occurrence. More formally, returns the the highest index <tt>i</tt>
  834. * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>,
  835. * or -1 if there is no such index. (Returns -1 if
  836. * <tt>target.size() > source.size()</tt>.)
  837. *
  838. * <p>This implementation uses the "brute force" technique of iterating
  839. * over the source list, looking for a match with the target at each
  840. * location in turn.
  841. *
  842. * @param source the list in which to search for the last occurrence
  843. * of <tt>target</tt>.
  844. * @param target the list to search for as a subList of <tt>source</tt>.
  845. * @return the starting position of the last occurrence of the specified
  846. * target list within the specified source list, or -1 if there
  847. * is no such occurrence.
  848. * @since 1.4
  849. */
  850. public static int lastIndexOfSubList(List source, List target) {
  851. int sourceSize = source.size();
  852. int targetSize = target.size();
  853. int maxCandidate = sourceSize - targetSize;
  854. if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
  855. source instanceof RandomAccess) { // Index access version
  856. nextCand:
  857. for (int candidate = maxCandidate; candidate >= 0; candidate--) {
  858. for (int i=0, j=candidate; i<targetSize; i++, j++)
  859. if (!eq(target.get(i), source.get(j)))
  860. continue nextCand; // Element mismatch, try next cand
  861. return candidate; // All elements of candidate matched target
  862. }
  863. } else { // Iterator version of above algorithm
  864. if (maxCandidate < 0)
  865. return -1;
  866. ListIterator si = source.listIterator(maxCandidate);
  867. nextCand:
  868. for (int candidate = maxCandidate; candidate >= 0; candidate--) {
  869. ListIterator ti = target.listIterator();
  870. for (int i=0; i<targetSize; i++) {
  871. if (!eq(ti.next(), si.next())) {
  872. if (candidate != 0) {
  873. // Back up source iterator to next candidate
  874. for (int j=0; j<=i+1; j++)
  875. si.previous();
  876. }
  877. continue nextCand;
  878. }
  879. }
  880. return candidate;
  881. }
  882. }
  883. return -1; // No candidate matched the target
  884. }
  885. // Unmodifiable Wrappers
  886. /**
  887. * Returns an unmodifiable view of the specified collection. This method
  888. * allows modules to provide users with "read-only" access to internal
  889. * collections. Query operations on the returned collection "read through"
  890. * to the specified collection, and attempts to modify the returned
  891. * collection, whether direct or via its iterator, result in an
  892. * <tt>UnsupportedOperationException</tt>.<p>
  893. *
  894. * The returned collection does <i>not</i> pass the hashCode and equals
  895. * operations through to the backing collection, but relies on
  896. * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods. This
  897. * is necessary to preserve the contracts of these operations in the case
  898. * that the backing collection is a set or a list.<p>
  899. *
  900. * The returned collection will be serializable if the specified collection
  901. * is serializable.
  902. *
  903. * @param c the collection for which an unmodifiable view is to be
  904. * returned.
  905. * @return an unmodifiable view of the specified collection.
  906. */
  907. public static Collection unmodifiableCollection(Collection c) {
  908. return new UnmodifiableCollection(c);
  909. }
  910. /**
  911. * @serial include
  912. */
  913. static class UnmodifiableCollection implements Collection, Serializable {
  914. // use serialVersionUID from JDK 1.2.2 for interoperability
  915. private static final long serialVersionUID = 1820017752578914078L;
  916. Collection c;
  917. UnmodifiableCollection(Collection c) {
  918. if (c==null)
  919. throw new NullPointerException();
  920. this.c = c;
  921. }
  922. public int size() {return c.size();}
  923. public boolean isEmpty() {return c.isEmpty();}
  924. public boolean contains(Object o) {return c.contains(o);}
  925. public Object[] toArray() {return c.toArray();}
  926. public Object[] toArray(Object[] a) {return c.toArray(a);}
  927. public String toString() {return c.toString();}
  928. public Iterator iterator() {
  929. return new Iterator() {
  930. Iterator i = c.iterator();
  931. public boolean hasNext() {return i.hasNext();}
  932. public Object next() {return i.next();}
  933. public void remove() {
  934. throw new UnsupportedOperationException();
  935. }
  936. };
  937. }
  938. public boolean add(Object o){
  939. throw new UnsupportedOperationException();
  940. }
  941. public boolean remove(Object o) {
  942. throw new UnsupportedOperationException();
  943. }
  944. public boolean containsAll(Collection coll) {
  945. return c.containsAll(coll);
  946. }
  947. public boolean addAll(Collection coll) {
  948. throw new UnsupportedOperationException();
  949. }
  950. public boolean removeAll(Collection coll) {
  951. throw new UnsupportedOperationException();
  952. }
  953. public boolean retainAll(Collection coll) {
  954. throw new UnsupportedOperationException();
  955. }
  956. public void clear() {
  957. throw new UnsupportedOperationException();
  958. }
  959. }
  960. /**
  961. * Returns an unmodifiable view of the specified set. This method allows
  962. * modules to provide users with "read-only" access to internal sets.
  963. * Query operations on the returned set "read through" to the specified
  964. * set, and attempts to modify the returned set, whether direct or via its
  965. * iterator, result in an <tt>UnsupportedOperationException</tt>.<p>
  966. *
  967. * The returned set will be serializable if the specified set
  968. * is serializable.
  969. *
  970. * @param s the set for which an unmodifiable view is to be returned.
  971. * @return an unmodifiable view of the specified set.
  972. */
  973. public static Set unmodifiableSet(Set s) {
  974. return new UnmodifiableSet(s);
  975. }
  976. /**
  977. * @serial include
  978. */
  979. static class UnmodifiableSet extends UnmodifiableCollection
  980. implements Set, Serializable {
  981. UnmodifiableSet(Set s) {super(s);}
  982. public boolean equals(Object o) {return c.equals(o);}
  983. public int hashCode() {return c.hashCode();}
  984. }
  985. /**
  986. * Returns an unmodifiable view of the specified sorted set. This method
  987. * allows modules to provide users with "read-only" access to internal
  988. * sorted sets. Query operations on the returned sorted set "read
  989. * through" to the specified sorted set. Attempts to modify the returned
  990. * sorted set, whether direct, via its iterator, or via its
  991. * <tt>subSet</tt>, <tt>headSet</tt>, or <tt>tailSet</tt> views, result in
  992. * an <tt>UnsupportedOperationException</tt>.<p>
  993. *
  994. * The returned sorted set will be serializable if the specified sorted set
  995. * is serializable.
  996. *
  997. * @param s the sorted set for which an unmodifiable view is to be
  998. * returned.
  999. * @return an unmodifiable view of the specified sorted set.
  1000. */
  1001. public static SortedSet unmodifiableSortedSet(SortedSet s) {
  1002. return new UnmodifiableSortedSet(s);
  1003. }
  1004. /**
  1005. * @serial include
  1006. */
  1007. static class UnmodifiableSortedSet extends UnmodifiableSet
  1008. implements SortedSet, Serializable {
  1009. private SortedSet ss;
  1010. UnmodifiableSortedSet(SortedSet s) {super(s); ss = s;}
  1011. public Comparator comparator() {return ss.comparator();}
  1012. public SortedSet subSet(Object fromElement, Object toElement) {
  1013. return new UnmodifiableSortedSet(ss.subSet(fromElement,toElement));
  1014. }
  1015. public SortedSet headSet(Object toElement) {
  1016. return new UnmodifiableSortedSet(ss.headSet(toElement));
  1017. }
  1018. public SortedSet tailSet(Object fromElement) {
  1019. return new UnmodifiableSortedSet(ss.tailSet(fromElement));
  1020. }
  1021. public Object first() {return ss.first();}
  1022. public Object last() {return ss.last();}
  1023. }
  1024. /**
  1025. * Returns an unmodifiable view of the specified list. This method allows
  1026. * modules to provide users with "read-only" access to internal
  1027. * lists. Query operations on the returned list "read through" to the
  1028. * specified list, and attempts to modify the returned list, whether
  1029. * direct or via its iterator, result in an
  1030. * <tt>UnsupportedOperationException</tt>.<p>
  1031. *
  1032. * The returned list will be serializable if the specified list
  1033. * is serializable. Similarly, the returned list will implement
  1034. * {@link RandomAccess} if the specified list does.
  1035. * the
  1036. *
  1037. * @param list the list for which an unmodifiable view is to be returned.
  1038. * @return an unmodifiable view of the specified list.
  1039. */
  1040. public static List unmodifiableList(List list) {
  1041. return (list instanceof RandomAccess ?
  1042. new UnmodifiableRandomAccessList(list) :
  1043. new UnmodifiableList(list));
  1044. }
  1045. /**
  1046. * @serial include
  1047. */
  1048. static class UnmodifiableList extends UnmodifiableCollection
  1049. implements List {
  1050. static final long serialVersionUID = -283967356065247728L;
  1051. List list;
  1052. UnmodifiableList(List list) {
  1053. super(list);
  1054. this.list = list;
  1055. }
  1056. public boolean equals(Object o) {return list.equals(o);}
  1057. public int hashCode() {return list.hashCode();}
  1058. public Object get(int index) {return list.get(index);}
  1059. public Object set(int index, Object element) {
  1060. throw new UnsupportedOperationException();
  1061. }
  1062. public void add(int index, Object element) {
  1063. throw new UnsupportedOperationException();
  1064. }
  1065. public Object remove(int index) {
  1066. throw new UnsupportedOperationException();
  1067. }
  1068. public int indexOf(Object o) {return list.indexOf(o);}
  1069. public int lastIndexOf(Object o) {return list.lastIndexOf(o);}
  1070. public boolean addAll(int index, Collection c) {
  1071. throw new UnsupportedOperationException();
  1072. }
  1073. public ListIterator listIterator() {return listIterator(0);}
  1074. public ListIterator listIterator(final int index) {
  1075. return new ListIterator() {
  1076. ListIterator i = list.listIterator(index);
  1077. public boolean hasNext() {return i.hasNext();}
  1078. public Object next() {return i.next();}
  1079. public boolean hasPrevious() {return i.hasPrevious();}
  1080. public Object previous() {return i.previous();}
  1081. public int nextIndex() {return i.nextIndex();}
  1082. public int previousIndex() {return i.previousIndex();}
  1083. public void remove() {
  1084. throw new UnsupportedOperationException();
  1085. }
  1086. public void set(Object o) {
  1087. throw new UnsupportedOperationException();
  1088. }
  1089. public void add(Object o) {
  1090. throw new UnsupportedOperationException();
  1091. }
  1092. };
  1093. }
  1094. public List subList(int fromIndex, int toIndex) {
  1095. return new UnmodifiableList(list.subList(fromIndex, toIndex));
  1096. }
  1097. /**
  1098. * UnmodifiableRandomAccessList instances are serialized as
  1099. * UnmodifiableList instances to allow them to be deserialized
  1100. * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).
  1101. * This method inverts the transformation. As a beneficial
  1102. * side-effect, it also grafts the RandomAccess marker onto
  1103. * UnmodifiableList instances that were serialized in pre-1.4 JREs.
  1104. *
  1105. * Note: Unfortunately, UnmodifiableRandomAccessList instances
  1106. * serialized in 1.4.1 and deserialized in 1.4 will become
  1107. * UnmodifiableList instances, as this method was missing in 1.4.
  1108. */
  1109. private Object readResolve() {
  1110. return (list instanceof RandomAccess ?
  1111. new UnmodifiableRandomAccessList(list) : this);
  1112. }
  1113. }
  1114. /**
  1115. * @serial include
  1116. */
  1117. static class UnmodifiableRandomAccessList extends UnmodifiableList
  1118. implements RandomAccess
  1119. {
  1120. UnmodifiableRandomAccessList(List list) {
  1121. super(list);
  1122. }
  1123. public List subList(int fromIndex, int toIndex) {
  1124. return new UnmodifiableRandomAccessList(
  1125. list.subList(fromIndex, toIndex));
  1126. }
  1127. private static final long serialVersionUID = -2542308836966382001L;
  1128. /**
  1129. * Allows instances to be deserialized in pre-1.4 JREs (which do
  1130. * not have UnmodifiableRandomAccessList). UnmodifiableList has
  1131. * a readResolve method that inverts this transformation upon
  1132. * deserialization.
  1133. */
  1134. private Object writeReplace() {
  1135. return new UnmodifiableList(list);
  1136. }
  1137. }
  1138. /**
  1139. * Returns an unmodifiable view of the specified map. This method
  1140. * allows modules to provide users with "read-only" access to internal
  1141. * maps. Query operations on the returned map "read through"
  1142. * to the specified map, and attempts to modify the returned
  1143. * map, whether direct or via its collection views, result in an
  1144. * <tt>UnsupportedOperationException</tt>.<p>
  1145. *
  1146. * The returned map will be serializable if the specified map
  1147. * is serializable.
  1148. *
  1149. * @param m the map for which an unmodifiable view is to be returned.
  1150. * @return an unmodifiable view of the specified map.
  1151. */
  1152. public static Map unmodifiableMap(Map m) {
  1153. return new UnmodifiableMap(m);
  1154. }
  1155. /**
  1156. * @serial include
  1157. */
  1158. private static class UnmodifiableMap implements Map, Serializable {
  1159. // use serialVersionUID from JDK 1.2.2 for interoperability
  1160. private static final long serialVersionUID = -1034234728574286014L;
  1161. private final Map m;
  1162. UnmodifiableMap(Map m) {
  1163. if (m==null)
  1164. throw new NullPointerException();
  1165. this.m = m;
  1166. }
  1167. public int size() {return m.size();}
  1168. public boolean isEmpty() {return m.isEmpty();}
  1169. public boolean containsKey(Object key) {return m.containsKey(key);}
  1170. public boolean containsValue(Object val) {return m.containsValue(val);}
  1171. public Object get(Object key) {return m.get(key);}
  1172. public Object put(Object key, Object value) {
  1173. throw new UnsupportedOperationException();
  1174. }
  1175. public Object remove(Object key) {
  1176. throw new UnsupportedOperationException();
  1177. }
  1178. public void putAll(Map t) {
  1179. throw new UnsupportedOperationException();
  1180. }
  1181. public void clear() {
  1182. throw new UnsupportedOperationException();
  1183. }
  1184. private transient Set keySet = null;
  1185. private transient Set entrySet = null;
  1186. private transient Collection values = null;
  1187. public Set keySet() {
  1188. if (keySet==null)
  1189. keySet = unmodifiableSet(m.keySet());
  1190. return keySet;
  1191. }
  1192. public Set entrySet() {
  1193. if (entrySet==null)
  1194. entrySet = new UnmodifiableEntrySet(m.entrySet());
  1195. return entrySet;
  1196. }
  1197. public Collection values() {
  1198. if (values==null)
  1199. values = unmodifiableCollection(m.values());
  1200. return values;
  1201. }
  1202. public boolean equals(Object o) {return m.equals(o);}
  1203. public int hashCode() {return m.hashCode();}
  1204. public String toString() {return m.toString();}
  1205. /**
  1206. * We need this class in addition to UnmodifiableSet as
  1207. * Map.Entries themselves permit modification of the backing Map
  1208. * via their setValue operation. This class is subtle: there are
  1209. * many possible attacks that must be thwarted.
  1210. *
  1211. * @serial include
  1212. */
  1213. static class UnmodifiableEntrySet extends UnmodifiableSet {
  1214. UnmodifiableEntrySet(Set s) {
  1215. super(s);
  1216. }
  1217. public Iterator iterator() {
  1218. return new Iterator() {
  1219. Iterator i = c.iterator();
  1220. public boolean hasNext() {
  1221. return i.hasNext();
  1222. }
  1223. public Object next() {
  1224. return new UnmodifiableEntry((Map.Entry)i.next());
  1225. }
  1226. public void remove() {
  1227. throw new UnsupportedOperationException();
  1228. }
  1229. };
  1230. }
  1231. public Object[] toArray() {
  1232. Object[] a = c.toArray();
  1233. for (int i=0; i<a.length; i++)
  1234. a[i] = new UnmodifiableEntry((Map.Entry)a[i]);
  1235. return a;
  1236. }
  1237. public Object[] toArray(Object a[]) {
  1238. // We don't pass a to c.toArray, to avoid window of
  1239. // vulnerability wherein an unscrupulous multithreaded client
  1240. // could get his hands on raw (unwrapped) Entries from c.
  1241. Object[] arr = c.toArray(a.length==0 ? a :
  1242. (Object[])java.lang.reflect.Array.newInstance(
  1243. a.getClass().getComponentType(), 0));
  1244. for (int i=0; i<arr.length; i++)
  1245. arr[i] = new UnmodifiableEntry((Map.Entry)arr[i]);
  1246. if (arr.length > a.length)
  1247. return arr;
  1248. System.arraycopy(arr, 0, a, 0, arr.length);
  1249. if (a.length > arr.length)
  1250. a[arr.length] = null;
  1251. return a;
  1252. }
  1253. /**
  1254. * This method is overridden to protect the backing set against
  1255. * an object with a nefarious equals function that senses
  1256. * that the equality-candidate is Map.Entry and calls its
  1257. * setValue method.
  1258. */
  1259. public boolean contains(Object o) {
  1260. if (!(o instanceof Map.Entry))
  1261. return false;
  1262. return c.contains(new UnmodifiableEntry((Map.Entry)o));
  1263. }
  1264. /**
  1265. * The next two methods are overridden to protect against
  1266. * an unscrupulous List whose contains(Object o) method senses
  1267. * when o is a Map.Entry, and calls o.setValue.
  1268. */
  1269. public boolean containsAll(Collection coll) {
  1270. Iterator e = coll.iterator();
  1271. while (e.hasNext())
  1272. if(!contains(e.next())) // Invokes safe contains() above
  1273. return false;
  1274. return true;
  1275. }
  1276. public boolean equals(Object o) {
  1277. if (o == this)
  1278. return true;
  1279. if (!(o instanceof Set))
  1280. return false;
  1281. Set s = (Set) o;
  1282. if (s.size() != c.size())
  1283. return false;
  1284. return containsAll(s); // Invokes safe containsAll() above
  1285. }
  1286. /**
  1287. * This "wrapper class" serves two purposes: it prevents
  1288. * the client from modifying the backing Map, by short-circuiting
  1289. * the setValue method, and it protects the backing Map against
  1290. * an ill-behaved Map.Entry that attempts to modify another
  1291. * Map Entry when asked to perform an equality check.
  1292. */
  1293. private static class UnmodifiableEntry implements Map.Entry {
  1294. private Map.Entry e;
  1295. UnmodifiableEntry(Map.Entry e) {this.e = e;}
  1296. public Object getKey() {return e.getKey();}
  1297. public Object getValue() {return e.getValue();}
  1298. public Object setValue(Object value) {
  1299. throw new UnsupportedOperationException();
  1300. }
  1301. public int hashCode() {return e.hashCode();}
  1302. public boolean equals(Object o) {
  1303. if (!(o instanceof Map.Entry))
  1304. return false;
  1305. Map.Entry t = (Map.Entry)o;
  1306. return eq(e.getKey(), t.getKey()) &&
  1307. eq(e.getValue(), t.getValue());
  1308. }
  1309. public String toString() {return e.toString();}
  1310. }
  1311. }
  1312. }
  1313. /**
  1314. * Returns an unmodifiable view of the specified sorted map. This method
  1315. * allows modules to provide users with "read-only" access to internal
  1316. * sorted maps. Query operations on the returned sorted map "read through"
  1317. * to the specified sorted map. Attempts to modify the returned
  1318. * sorted map, whether direct, via its collection views, or via its
  1319. * <tt>subMap</tt>, <tt>headMap</tt>, or <tt>tailMap</tt> views, result in
  1320. * an <tt>UnsupportedOperationException</tt>.<p>
  1321. *
  1322. * The returned sorted map will be serializable if the specified sorted map
  1323. * is serializable.
  1324. *
  1325. * @param m the sorted map for which an unmodifiable view is to be
  1326. * returned.
  1327. * @return an unmodifiable view of the specified sorted map.
  1328. */
  1329. public static SortedMap unmodifiableSortedMap(SortedMap m) {
  1330. return new UnmodifiableSortedMap(m);
  1331. }
  1332. /**
  1333. * @serial include
  1334. */
  1335. static class UnmodifiableSortedMap extends UnmodifiableMap
  1336. implements SortedMap, Serializable {
  1337. private SortedMap sm;
  1338. UnmodifiableSortedMap(SortedMap m) {super(m); sm = m;}
  1339. public Comparator comparator() {return sm.comparator();}
  1340. public SortedMap subMap(Object fromKey, Object toKey) {
  1341. return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
  1342. }
  1343. public SortedMap headMap(Object toKey) {
  1344. return new UnmodifiableSortedMap(sm.headMap(toKey));
  1345. }
  1346. public SortedMap tailMap(Object fromKey) {
  1347. return new UnmodifiableSortedMap(sm.tailMap(fromKey));
  1348. }
  1349. public Object firstKey() {return sm.firstKey();}
  1350. public Object lastKey() {return sm.lastKey();}
  1351. }
  1352. // Synch Wrappers
  1353. /**
  1354. * Returns a synchronized (thread-safe) collection backed by the specified
  1355. * collection. In order to guarantee serial access, it is critical that
  1356. * <strong>all</strong> access to the backing collection is accomplished
  1357. * through the returned collection.<p>
  1358. *
  1359. * It is imperative that the user manually synchronize on the returned
  1360. * collection when iterating over it:
  1361. * <pre>
  1362. * Collection c = Collections.synchronizedCollection(myCollection);
  1363. * ...
  1364. * synchronized(c) {
  1365. * Iterator i = c.iterator(); // Must be in the synchronized block
  1366. * while (i.hasNext())
  1367. * foo(i.next());
  1368. * }
  1369. * </pre>
  1370. * Failure to follow this advice may result in non-deterministic behavior.
  1371. *
  1372. * <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt>
  1373. * and <tt>equals</tt> operations through to the backing collection, but
  1374. * relies on <tt>Object</tt>'s equals and hashCode methods. This is
  1375. * necessary to preserve the contracts of these operations in the case
  1376. * that the backing collection is a set or a list.<p>
  1377. *
  1378. * The returned collection will be serializable if the specified collection
  1379. * is serializable.
  1380. *
  1381. * @param c the collection to be "wrapped" in a synchronized collection.
  1382. * @return a synchronized view of the specified collection.
  1383. */
  1384. public static Collection synchronizedCollection(Collection c) {
  1385. return new SynchronizedCollection(c);
  1386. }
  1387. static Collection synchronizedCollection(Collection c, Object mutex) {
  1388. return new SynchronizedCollection(c, mutex);
  1389. }
  1390. /**
  1391. * @serial include
  1392. */
  1393. static class SynchronizedCollection implements Collection, Serializable {
  1394. // use serialVersionUID from JDK 1.2.2 for interoperability
  1395. private static final long serialVersionUID = 3053995032091335093L;
  1396. Collection c; // Backing Collection
  1397. Object mutex; // Object on which to synchronize
  1398. SynchronizedCollection(Collection c) {
  1399. if (c==null)
  1400. throw new NullPointerException();
  1401. this.c = c;
  1402. mutex = this;
  1403. }
  1404. SynchronizedCollection(Collection c, Object mutex) {
  1405. this.c = c;
  1406. this.mutex = mutex;
  1407. }
  1408. public int size() {
  1409. synchronized(mutex) {return c.size();}
  1410. }
  1411. public boolean isEmpty() {
  1412. synchronized(mutex) {return c.isEmpty();}
  1413. }
  1414. public boolean contains(Object o) {
  1415. synchronized(mutex) {return c.contains(o);}
  1416. }
  1417. public Object[] toArray() {
  1418. synchronized(mutex) {return c.toArray();}
  1419. }
  1420. public Object[] toArray(Object[] a) {
  1421. synchronized(mutex) {return c.toArray(a);}
  1422. }
  1423. public Iterator iterator() {
  1424. return c.iterator(); // Must be manually synched by user!
  1425. }
  1426. public boolean add(Object o) {
  1427. synchronized(mutex) {return c.add(o);}
  1428. }
  1429. public boolean remove(Object o) {
  1430. synchronized(mutex) {return c.remove(o);}
  1431. }
  1432. public boolean containsAll(Collection coll) {
  1433. synchronized(mutex) {return c.containsAll(coll);}
  1434. }
  1435. public boolean addAll(Collection coll) {
  1436. synchronized(mutex) {return c.addAll(coll);}
  1437. }
  1438. public boolean removeAll(Collection coll) {
  1439. synchronized(mutex) {return c.removeAll(coll);}
  1440. }
  1441. public boolean retainAll(Collection coll) {
  1442. synchronized(mutex) {return c.retainAll(coll);}
  1443. }
  1444. public void clear() {
  1445. synchronized(mutex) {c.clear();}
  1446. }
  1447. public String toString() {
  1448. synchronized(mutex) {return c.toString();}
  1449. }
  1450. }
  1451. /**
  1452. * Returns a synchronized (thread-safe) set backed by the specified
  1453. * set. In order to guarantee serial access, it is critical that
  1454. * <strong>all</strong> access to the backing set is accomplished
  1455. * through the returned set.<p>
  1456. *
  1457. * It is imperative that the user manually synchronize on the returned
  1458. * set when iterating over it:
  1459. * <pre>
  1460. * Set s = Collections.synchronizedSet(new HashSet());
  1461. * ...
  1462. * synchronized(s) {
  1463. * Iterator i = s.iterator(); // Must be in the synchronized block
  1464. * while (i.hasNext())
  1465. * foo(i.next());
  1466. * }
  1467. * </pre>
  1468. * Failure to follow this advice may result in non-deterministic behavior.
  1469. *
  1470. * <p>The returned set will be serializable if the specified set is
  1471. * serializable.
  1472. *
  1473. * @param s the set to be "wrapped" in a synchronized set.
  1474. * @return a synchronized view of the specified set.
  1475. */
  1476. public static Set synchronizedSet(Set s) {
  1477. return new SynchronizedSet(s);
  1478. }
  1479. static Set synchronizedSet(Set s, Object mutex) {
  1480. return new SynchronizedSet(s, mutex);
  1481. }
  1482. /**
  1483. * @serial include
  1484. */
  1485. static class SynchronizedSet extends SynchronizedCollection
  1486. implements Set {
  1487. SynchronizedSet(Set s) {
  1488. super(s);
  1489. }
  1490. SynchronizedSet(Set s, Object mutex) {
  1491. super(s, mutex);
  1492. }
  1493. public boolean equals(Object o) {
  1494. synchronized(mutex) {return c.equals(o);}
  1495. }
  1496. public int hashCode() {
  1497. synchronized(mutex) {return c.hashCode();}
  1498. }
  1499. }
  1500. /**
  1501. * Returns a synchronized (thread-safe) sorted set backed by the specified
  1502. * sorted set. In order to guarantee serial access, it is critical that
  1503. * <strong>all</strong> access to the backing sorted set is accomplished
  1504. * through the returned sorted set (or its views).<p>
  1505. *
  1506. * It is imperative that the user manually synchronize on the returned
  1507. * sorted set when iterating over it or any of its <tt>subSet</tt>,
  1508. * <tt>headSet</tt>, or <tt>tailSet</tt> views.
  1509. * <pre>
  1510. * SortedSet s = Collections.synchronizedSortedSet(new HashSortedSet());
  1511. * ...
  1512. * synchronized(s) {
  1513. * Iterator i = s.iterator(); // Must be in the synchronized block
  1514. * while (i.hasNext())
  1515. * foo(i.next());
  1516. * }
  1517. * </pre>
  1518. * or:
  1519. * <pre>
  1520. * SortedSet s = Collections.synchronizedSortedSet(new HashSortedSet());
  1521. * SortedSet s2 = s.headSet(foo);
  1522. * ...
  1523. * synchronized(s) { // Note: s, not s2!!!
  1524. * Iterator i = s2.iterator(); // Must be in the synchronized block
  1525. * while (i.hasNext())
  1526. * foo(i.next());
  1527. * }
  1528. * </pre>
  1529. * Failure to follow this advice may result in non-deterministic behavior.
  1530. *
  1531. * <p>The returned sorted set will be serializable if the specified
  1532. * sorted set is serializable.
  1533. *
  1534. * @param s the sorted set to be "wrapped" in a synchronized sorted set.
  1535. * @return a synchronized view of the specified sorted set.
  1536. */
  1537. public static SortedSet synchronizedSortedSet(SortedSet s) {
  1538. return new SynchronizedSortedSet(s);
  1539. }
  1540. /**
  1541. * @serial include
  1542. */
  1543. static class SynchronizedSortedSet extends SynchronizedSet
  1544. implements SortedSet
  1545. {
  1546. private SortedSet ss;
  1547. SynchronizedSortedSet(SortedSet s) {
  1548. super(s);
  1549. ss = s;
  1550. }
  1551. SynchronizedSortedSet(SortedSet s, Object mutex) {
  1552. super(s, mutex);
  1553. ss = s;
  1554. }
  1555. public Comparator comparator() {
  1556. synchronized(mutex) {return ss.comparator();}
  1557. }
  1558. public SortedSet subSet(Object fromElement, Object toElement) {
  1559. synchronized(mutex) {
  1560. return new SynchronizedSortedSet(
  1561. ss.subSet(fromElement, toElement), mutex);
  1562. }
  1563. }
  1564. public SortedSet headSet(Object toElement) {
  1565. synchronized(mutex) {
  1566. return new SynchronizedSortedSet(ss.headSet(toElement), mutex);
  1567. }
  1568. }
  1569. public SortedSet tailSet(Object fromElement) {
  1570. synchronized(mutex) {
  1571. return new SynchronizedSortedSet(ss.tailSet(fromElement),mutex);
  1572. }
  1573. }
  1574. public Object first() {
  1575. synchronized(mutex) {return ss.first();}
  1576. }
  1577. public Object last() {
  1578. synchronized(mutex) {return ss.last();}
  1579. }
  1580. }
  1581. /**
  1582. * Returns a synchronized (thread-safe) list backed by the specified
  1583. * list. In order to guarantee serial access, it is critical that
  1584. * <strong>all</strong> access to the backing list is accomplished
  1585. * through the returned list.<p>
  1586. *
  1587. * It is imperative that the user manually synchronize on the returned
  1588. * list when iterating over it:
  1589. * <pre>
  1590. * List list = Collections.synchronizedList(new ArrayList());
  1591. * ...
  1592. * synchronized(list) {
  1593. * Iterator i = list.iterator(); // Must be in synchronized block
  1594. * while (i.hasNext())
  1595. * foo(i.next());
  1596. * }
  1597. * </pre>
  1598. * Failure to follow this advice may result in non-deterministic behavior.
  1599. *
  1600. * <p>The returned list will be serializable if the specified list is
  1601. * serializable.
  1602. *
  1603. * @param list the list to be "wrapped" in a synchronized list.
  1604. * @return a synchronized view of the specified list.
  1605. */
  1606. public static List synchronizedList(List list) {
  1607. return (list instanceof RandomAccess ?
  1608. new SynchronizedRandomAccessList(list) :
  1609. new SynchronizedList(list));
  1610. }
  1611. static List synchronizedList(List list, Object mutex) {
  1612. return (list instanceof RandomAccess ?
  1613. new SynchronizedRandomAccessList(list, mutex) :
  1614. new SynchronizedList(list, mutex));
  1615. }
  1616. /**
  1617. * @serial include
  1618. */
  1619. static class SynchronizedList extends SynchronizedCollection
  1620. implements List {
  1621. static final long serialVersionUID = -7754090372962971524L;
  1622. List list;
  1623. SynchronizedList(List list) {
  1624. super(list);
  1625. this.list = list;
  1626. }
  1627. SynchronizedList(List list, Object mutex) {
  1628. super(list, mutex);
  1629. this.list = list;
  1630. }
  1631. public boolean equals(Object o) {
  1632. synchronized(mutex) {return list.equals(o);}
  1633. }
  1634. public int hashCode() {
  1635. synchronized(mutex) {return list.hashCode();}
  1636. }
  1637. public Object get(int index) {
  1638. synchronized(mutex) {return list.get(index);}
  1639. }
  1640. public Object set(int index, Object element) {
  1641. synchronized(mutex) {return list.set(index, element);}
  1642. }
  1643. public void add(int index, Object element) {
  1644. synchronized(mutex) {list.add(index, element);}
  1645. }
  1646. public Object remove(int index) {
  1647. synchronized(mutex) {return list.remove(index);}
  1648. }
  1649. public int indexOf(Object o) {
  1650. synchronized(mutex) {return list.indexOf(o);}
  1651. }
  1652. public int lastIndexOf(Object o) {
  1653. synchronized(mutex) {return list.lastIndexOf(o);}
  1654. }
  1655. public boolean addAll(int index, Collection c) {
  1656. synchronized(mutex) {return list.addAll(index, c);}
  1657. }
  1658. public ListIterator listIterator() {
  1659. return list.listIterator(); // Must be manually synched by user
  1660. }
  1661. public ListIterator listIterator(int index) {
  1662. return list.listIterator(index); // Must be manually synched by usr
  1663. }
  1664. public List subList(int fromIndex, int toIndex) {
  1665. synchronized(mutex) {
  1666. return new SynchronizedList(list.subList(fromIndex, toIndex),
  1667. mutex);
  1668. }
  1669. }
  1670. /**
  1671. * SynchronizedRandomAccessList instances are serialized as
  1672. * SynchronizedList instances to allow them to be deserialized
  1673. * in pre-1.4 JREs (which do not have SynchronizedRandomAccessList).
  1674. * This method inverts the transformation. As a beneficial
  1675. * side-effect, it also grafts the RandomAccess marker onto
  1676. * SynchronizedList instances that were serialized in pre-1.4 JREs.
  1677. *
  1678. * Note: Unfortunately, SynchronizedRandomAccessList instances
  1679. * serialized in 1.4.1 and deserialized in 1.4 will become
  1680. * SynchronizedList instances, as this method was missing in 1.4.
  1681. */
  1682. private Object readResolve() {
  1683. return (list instanceof RandomAccess ?
  1684. new SynchronizedRandomAccessList(list) : this);
  1685. }
  1686. }
  1687. /**
  1688. * @serial include
  1689. */
  1690. static class SynchronizedRandomAccessList extends SynchronizedList
  1691. implements RandomAccess
  1692. {
  1693. SynchronizedRandomAccessList(List list) {
  1694. super(list);
  1695. }
  1696. SynchronizedRandomAccessList(List list, Object mutex) {
  1697. super(list, mutex);
  1698. }
  1699. public List subList(int fromIndex, int toIndex) {
  1700. synchronized(mutex) {
  1701. return new SynchronizedRandomAccessList(
  1702. list.subList(fromIndex, toIndex), mutex);
  1703. }
  1704. }
  1705. static final long serialVersionUID = 1530674583602358482L;
  1706. /**
  1707. * Allows instances to be deserialized in pre-1.4 JREs (which do
  1708. * not have SynchronizedRandomAccessList). SynchronizedList has
  1709. * a readResolve method that inverts this transformation upon
  1710. * deserialization.
  1711. */
  1712. private Object writeReplace() {
  1713. return new SynchronizedList(list);
  1714. }
  1715. }
  1716. /**
  1717. * Returns a synchronized (thread-safe) map backed by the specified
  1718. * map. In order to guarantee serial access, it is critical that
  1719. * <strong>all</strong> access to the backing map is accomplished
  1720. * through the returned map.<p>
  1721. *
  1722. * It is imperative that the user manually synchronize on the returned
  1723. * map when iterating over any of its collection views:
  1724. * <pre>
  1725. * Map m = Collections.synchronizedMap(new HashMap());
  1726. * ...
  1727. * Set s = m.keySet(); // Needn't be in synchronized block
  1728. * ...
  1729. * synchronized(m) { // Synchronizing on m, not s!
  1730. * Iterator i = s.iterator(); // Must be in synchronized block
  1731. * while (i.hasNext())
  1732. * foo(i.next());
  1733. * }
  1734. * </pre>
  1735. * Failure to follow this advice may result in non-deterministic behavior.
  1736. *
  1737. * <p>The returned map will be serializable if the specified map is
  1738. * serializable.
  1739. *
  1740. * @param m the map to be "wrapped" in a synchronized map.
  1741. * @return a synchronized view of the specified map.
  1742. */
  1743. public static Map synchronizedMap(Map m) {
  1744. return new SynchronizedMap(m);
  1745. }
  1746. /**
  1747. * @serial include
  1748. */
  1749. private static class SynchronizedMap implements Map, Serializable {
  1750. // use serialVersionUID from JDK 1.2.2 for interoperability
  1751. private static final long serialVersionUID = 1978198479659022715L;
  1752. private Map m; // Backing Map
  1753. Object mutex; // Object on which to synchronize
  1754. SynchronizedMap(Map m) {
  1755. if (m==null)
  1756. throw new NullPointerException();
  1757. this.m = m;
  1758. mutex = this;
  1759. }
  1760. SynchronizedMap(Map m, Object mutex) {
  1761. this.m = m;
  1762. this.mutex = mutex;
  1763. }
  1764. public int size() {
  1765. synchronized(mutex) {return m.size();}
  1766. }
  1767. public boolean isEmpty(){
  1768. synchronized(mutex) {return m.isEmpty();}
  1769. }
  1770. public boolean containsKey(Object key) {
  1771. synchronized(mutex) {return m.containsKey(key);}
  1772. }
  1773. public boolean containsValue(Object value){
  1774. synchronized(mutex) {return m.containsValue(value);}
  1775. }
  1776. public Object get(Object key) {
  1777. synchronized(mutex) {return m.get(key);}
  1778. }
  1779. public Object put(Object key, Object value) {
  1780. synchronized(mutex) {return m.put(key, value);}
  1781. }
  1782. public Object remove(Object key) {
  1783. synchronized(mutex) {return m.remove(key);}
  1784. }
  1785. public void putAll(Map map) {
  1786. synchronized(mutex) {m.putAll(map);}
  1787. }
  1788. public void clear() {
  1789. synchronized(mutex) {m.clear();}
  1790. }
  1791. private transient Set keySet = null;
  1792. private transient Set entrySet = null;
  1793. private transient Collection values = null;
  1794. public Set keySet() {
  1795. synchronized(mutex) {
  1796. if (keySet==null)
  1797. keySet = new SynchronizedSet(m.keySet(), mutex);
  1798. return keySet;
  1799. }
  1800. }
  1801. public Set entrySet() {
  1802. synchronized(mutex) {
  1803. if (entrySet==null)
  1804. entrySet = new SynchronizedSet(m.entrySet(), mutex);
  1805. return entrySet;
  1806. }
  1807. }
  1808. public Collection values() {
  1809. synchronized(mutex) {
  1810. if (values==null)
  1811. values = new SynchronizedCollection(m.values(), mutex);
  1812. return values;
  1813. }
  1814. }
  1815. public boolean equals(Object o) {
  1816. synchronized(mutex) {return m.equals(o);}
  1817. }
  1818. public int hashCode() {
  1819. synchronized(mutex) {return m.hashCode();}
  1820. }
  1821. public String toString() {
  1822. synchronized(mutex) {return m.toString();}
  1823. }
  1824. }
  1825. /**
  1826. * Returns a synchronized (thread-safe) sorted map backed by the specified
  1827. * sorted map. In order to guarantee serial access, it is critical that
  1828. * <strong>all</strong> access to the backing sorted map is accomplished
  1829. * through the returned sorted map (or its views).<p>
  1830. *
  1831. * It is imperative that the user manually synchronize on the returned
  1832. * sorted map when iterating over any of its collection views, or the
  1833. * collections views of any of its <tt>subMap</tt>, <tt>headMap</tt> or
  1834. * <tt>tailMap</tt> views.
  1835. * <pre>
  1836. * SortedMap m = Collections.synchronizedSortedMap(new HashSortedMap());
  1837. * ...
  1838. * Set s = m.keySet(); // Needn't be in synchronized block
  1839. * ...
  1840. * synchronized(m) { // Synchronizing on m, not s!
  1841. * Iterator i = s.iterator(); // Must be in synchronized block
  1842. * while (i.hasNext())
  1843. * foo(i.next());
  1844. * }
  1845. * </pre>
  1846. * or:
  1847. * <pre>
  1848. * SortedMap m = Collections.synchronizedSortedMap(new HashSortedMap());
  1849. * SortedMap m2 = m.subMap(foo, bar);
  1850. * ...
  1851. * Set s2 = m2.keySet(); // Needn't be in synchronized block
  1852. * ...
  1853. * synchronized(m) { // Synchronizing on m, not m2 or s2!
  1854. * Iterator i = s.iterator(); // Must be in synchronized block
  1855. * while (i.hasNext())
  1856. * foo(i.next());
  1857. * }
  1858. * </pre>
  1859. * Failure to follow this advice may result in non-deterministic behavior.
  1860. *
  1861. * <p>The returned sorted map will be serializable if the specified
  1862. * sorted map is serializable.
  1863. *
  1864. * @param m the sorted map to be "wrapped" in a synchronized sorted map.
  1865. * @return a synchronized view of the specified sorted map.
  1866. */
  1867. public static SortedMap synchronizedSortedMap(SortedMap m) {
  1868. return new SynchronizedSortedMap(m);
  1869. }
  1870. /**
  1871. * @serial include
  1872. */
  1873. static class SynchronizedSortedMap extends SynchronizedMap
  1874. implements SortedMap
  1875. {
  1876. private SortedMap sm;
  1877. SynchronizedSortedMap(SortedMap m) {
  1878. super(m);
  1879. sm = m;
  1880. }
  1881. SynchronizedSortedMap(SortedMap m, Object mutex) {
  1882. super(m, mutex);
  1883. sm = m;
  1884. }
  1885. public Comparator comparator() {
  1886. synchronized(mutex) {return sm.comparator();}
  1887. }
  1888. public SortedMap subMap(Object fromKey, Object toKey) {
  1889. synchronized(mutex) {
  1890. return new SynchronizedSortedMap(
  1891. sm.subMap(fromKey, toKey), mutex);
  1892. }
  1893. }
  1894. public SortedMap headMap(Object toKey) {
  1895. synchronized(mutex) {
  1896. return new SynchronizedSortedMap(sm.headMap(toKey), mutex);
  1897. }
  1898. }
  1899. public SortedMap tailMap(Object fromKey) {
  1900. synchronized(mutex) {
  1901. return new SynchronizedSortedMap(sm.tailMap(fromKey),mutex);
  1902. }
  1903. }
  1904. public Object firstKey() {
  1905. synchronized(mutex) {return sm.firstKey();}
  1906. }
  1907. public Object lastKey() {
  1908. synchronized(mutex) {return sm.lastKey();}
  1909. }
  1910. }
  1911. // Miscellaneous
  1912. /**
  1913. * The empty set (immutable). This set is serializable.
  1914. */
  1915. public static final Set EMPTY_SET = new EmptySet();
  1916. /**
  1917. * @serial include
  1918. */
  1919. private static class EmptySet extends AbstractSet implements Serializable {
  1920. // use serialVersionUID from JDK 1.2.2 for interoperability
  1921. private static final long serialVersionUID = 1582296315990362920L;
  1922. public Iterator iterator() {
  1923. return new Iterator() {
  1924. public boolean hasNext() {
  1925. return false;
  1926. }
  1927. public Object next() {
  1928. throw new NoSuchElementException();
  1929. }
  1930. public void remove() {
  1931. throw new UnsupportedOperationException();
  1932. }
  1933. };
  1934. }
  1935. public int size() {return 0;}
  1936. public boolean contains(Object obj) {return false;}
  1937. // Preserves singleton property
  1938. private Object readResolve() {
  1939. return EMPTY_SET;
  1940. }
  1941. }
  1942. /**
  1943. * The empty list (immutable). This list is serializable.
  1944. */
  1945. public static final List EMPTY_LIST = new EmptyList();
  1946. /**
  1947. * @serial include
  1948. */
  1949. private static class EmptyList extends AbstractList
  1950. implements RandomAccess, Serializable {
  1951. // use serialVersionUID from JDK 1.2.2 for interoperability
  1952. private static final long serialVersionUID = 8842843931221139166L;
  1953. public int size() {return 0;}
  1954. public boolean contains(Object obj) {return false;}
  1955. public Object get(int index) {
  1956. throw new IndexOutOfBoundsException("Index: "+index);
  1957. }
  1958. // Preserves singleton property
  1959. private Object readResolve() {
  1960. return EMPTY_LIST;
  1961. }
  1962. }
  1963. /**
  1964. * The empty map (immutable). This map is serializable.
  1965. *
  1966. * @since 1.3
  1967. */
  1968. public static final Map EMPTY_MAP = new EmptyMap();
  1969. private static class EmptyMap extends AbstractMap implements Serializable {
  1970. private static final long serialVersionUID = 6428348081105594320L;
  1971. public int size() {return 0;}
  1972. public boolean isEmpty() {return true;}
  1973. public boolean containsKey(Object key) {return false;}
  1974. public boolean containsValue(Object value) {return false;}
  1975. public Object get(Object key) {return null;}
  1976. public Set keySet() {return EMPTY_SET;}
  1977. public Collection values() {return EMPTY_SET;}
  1978. public Set entrySet() {return EMPTY_SET;}
  1979. public boolean equals(Object o) {
  1980. return (o instanceof Map) && ((Map)o).size()==0;
  1981. }
  1982. public int hashCode() {return 0;}
  1983. // Preserves singleton property
  1984. private Object readResolve() {
  1985. return EMPTY_MAP;
  1986. }
  1987. }
  1988. /**
  1989. * Returns an immutable set containing only the specified object.
  1990. * The returned set is serializable.
  1991. *
  1992. * @param o the sole object to be stored in the returned set.
  1993. * @return an immutable set containing only the specified object.
  1994. */
  1995. public static Set singleton(Object o) {
  1996. return new SingletonSet(o);
  1997. }
  1998. /**
  1999. * @serial include
  2000. */
  2001. private static class SingletonSet extends AbstractSet
  2002. implements Serializable
  2003. {
  2004. // use serialVersionUID from JDK 1.2.2 for interoperability
  2005. private static final long serialVersionUID = 3193687207550431679L;
  2006. private Object element;
  2007. SingletonSet(Object o) {element = o;}
  2008. public Iterator iterator() {
  2009. return new Iterator() {
  2010. private boolean hasNext = true;
  2011. public boolean hasNext() {
  2012. return hasNext;
  2013. }
  2014. public Object next() {
  2015. if (hasNext) {
  2016. hasNext = false;
  2017. return element;
  2018. }
  2019. throw new NoSuchElementException();
  2020. }
  2021. public void remove() {
  2022. throw new UnsupportedOperationException();
  2023. }
  2024. };
  2025. }
  2026. public int size() {return 1;}
  2027. public boolean contains(Object o) {return eq(o, element);}
  2028. }
  2029. /**
  2030. * Returns an immutable list containing only the specified object.
  2031. * The returned list is serializable.
  2032. *
  2033. * @param o the sole object to be stored in the returned list.
  2034. * @return an immutable list containing only the specified object.
  2035. * @since 1.3
  2036. */
  2037. public static List singletonList(Object o) {
  2038. return new SingletonList(o);
  2039. }
  2040. private static class SingletonList extends AbstractList
  2041. implements RandomAccess, Serializable {
  2042. static final long serialVersionUID = 3093736618740652951L;
  2043. private final Object element;
  2044. SingletonList(Object obj) {element = obj;}
  2045. public int size() {return 1;}
  2046. public boolean contains(Object obj) {return eq(obj, element);}
  2047. public Object get(int index) {
  2048. if (index != 0)
  2049. throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
  2050. return element;
  2051. }
  2052. }
  2053. /**
  2054. * Returns an immutable map, mapping only the specified key to the
  2055. * specified value. The returned map is serializable.
  2056. *
  2057. * @param key the sole key to be stored in the returned map.
  2058. * @param value the value to which the returned map maps <tt>key</tt>.
  2059. * @return an immutable map containing only the specified key-value
  2060. * mapping.
  2061. * @since 1.3
  2062. */
  2063. public static Map singletonMap(Object key, Object value) {
  2064. return new SingletonMap(key, value);
  2065. }
  2066. private static class SingletonMap extends AbstractMap
  2067. implements Serializable {
  2068. private final Object k, v;
  2069. SingletonMap(Object key, Object value) {
  2070. k = key;
  2071. v = value;
  2072. }
  2073. public int size() {return 1;}
  2074. public boolean isEmpty() {return false;}
  2075. public boolean containsKey(Object key) {return eq(key, k);}
  2076. public boolean containsValue(Object value) {return eq(value, v);}
  2077. public Object get(Object key) {return (eq(key, k) ? v : null);}
  2078. private transient Set keySet = null;
  2079. private transient Set entrySet = null;
  2080. private transient Collection values = null;
  2081. public Set keySet() {
  2082. if (keySet==null)
  2083. keySet = singleton(k);
  2084. return keySet;
  2085. }
  2086. public Set entrySet() {
  2087. if (entrySet==null)
  2088. entrySet = singleton(new ImmutableEntry(k, v));
  2089. return entrySet;
  2090. }
  2091. public Collection values() {
  2092. if (values==null)
  2093. values = singleton(v);
  2094. return values;
  2095. }
  2096. private static class ImmutableEntry implements Map.Entry {
  2097. final Object k;
  2098. final Object v;
  2099. ImmutableEntry(Object key, Object value) {
  2100. k = key;
  2101. v = value;
  2102. }
  2103. public Object getKey() {return k;}
  2104. public Object getValue() {return v;}
  2105. public Object setValue(Object value) {
  2106. throw new UnsupportedOperationException();
  2107. }
  2108. public boolean equals(Object o) {
  2109. if (!(o instanceof Map.Entry))
  2110. return false;
  2111. Map.Entry e = (Map.Entry)o;
  2112. return eq(e.getKey(), k) && eq(e.getValue(), v);
  2113. }
  2114. public int hashCode() {
  2115. return ((k==null ? 0 : k.hashCode()) ^
  2116. (v==null ? 0 : v.hashCode()));
  2117. }
  2118. public String toString() {
  2119. return k+"="+v;
  2120. }
  2121. }
  2122. }
  2123. /**
  2124. * Returns an immutable list consisting of <tt>n</tt> copies of the
  2125. * specified object. The newly allocated data object is tiny (it contains
  2126. * a single reference to the data object). This method is useful in
  2127. * combination with the <tt>List.addAll</tt> method to grow lists.
  2128. * The returned list is serializable.
  2129. *
  2130. * @param n the number of elements in the returned list.
  2131. * @param o the element to appear repeatedly in the returned list.
  2132. * @return an immutable list consisting of <tt>n</tt> copies of the
  2133. * specified object.
  2134. * @throws IllegalArgumentException if n < 0.
  2135. * @see List#addAll(Collection)
  2136. * @see List#addAll(int, Collection)
  2137. */
  2138. public static List nCopies(int n, Object o) {
  2139. return new CopiesList(n, o);
  2140. }
  2141. /**
  2142. * @serial include
  2143. */
  2144. private static class CopiesList extends AbstractList
  2145. implements RandomAccess, Serializable
  2146. {
  2147. static final long serialVersionUID = 2739099268398711800L;
  2148. int n;
  2149. Object element;
  2150. CopiesList(int n, Object o) {
  2151. if (n < 0)
  2152. throw new IllegalArgumentException("List length = " + n);
  2153. this.n = n;
  2154. element = o;
  2155. }
  2156. public int size() {
  2157. return n;
  2158. }
  2159. public boolean contains(Object obj) {
  2160. return n != 0 && eq(obj, element);
  2161. }
  2162. public Object get(int index) {
  2163. if (index<0 || index>=n)
  2164. throw new IndexOutOfBoundsException("Index: "+index+
  2165. ", Size: "+n);
  2166. return element;
  2167. }
  2168. }
  2169. /**
  2170. * Returns a comparator that imposes the reverse of the <i>natural
  2171. * ordering</i> on a collection of objects that implement the
  2172. * <tt>Comparable</tt> interface. (The natural ordering is the ordering
  2173. * imposed by the objects' own <tt>compareTo</tt> method.) This enables a
  2174. * simple idiom for sorting (or maintaining) collections (or arrays) of
  2175. * objects that implement the <tt>Comparable</tt> interface in
  2176. * reverse-natural-order. For example, suppose a is an array of
  2177. * strings. Then: <pre>
  2178. * Arrays.sort(a, Collections.reverseOrder());
  2179. * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
  2180. *
  2181. * The returned comparator is serializable.
  2182. *
  2183. * @return a comparator that imposes the reverse of the <i>natural
  2184. * ordering</i> on a collection of objects that implement
  2185. * the <tt>Comparable</tt> interface.
  2186. * @see Comparable
  2187. */
  2188. public static Comparator reverseOrder() {
  2189. return REVERSE_ORDER;
  2190. }
  2191. private static final Comparator REVERSE_ORDER = new ReverseComparator();
  2192. /**
  2193. * @serial include
  2194. */
  2195. private static class ReverseComparator implements Comparator,Serializable {
  2196. // use serialVersionUID from JDK 1.2.2 for interoperability
  2197. private static final long serialVersionUID = 7207038068494060240L;
  2198. public int compare(Object o1, Object o2) {
  2199. Comparable c1 = (Comparable)o1;
  2200. Comparable c2 = (Comparable)o2;
  2201. int cmp = c1.compareTo(c2);
  2202. /*
  2203. * We can't simply return -cmp, as -Integer.MIN_VALUE ==
  2204. * Integer.MIN_VALUE.
  2205. */
  2206. return -(cmp | (cmp >>> 1));
  2207. }
  2208. }
  2209. /**
  2210. * Returns an enumeration over the specified collection. This provides
  2211. * interoperatbility with legacy APIs that require an enumeration
  2212. * as input.
  2213. *
  2214. * @param c the collection for which an enumeration is to be returned.
  2215. * @return an enumeration over the specified collection.
  2216. * @see Enumeration
  2217. */
  2218. public static Enumeration enumeration(final Collection c) {
  2219. return new Enumeration() {
  2220. Iterator i = c.iterator();
  2221. public boolean hasMoreElements() {
  2222. return i.hasNext();
  2223. }
  2224. public Object nextElement() {
  2225. return i.next();
  2226. }
  2227. };
  2228. }
  2229. /**
  2230. * Returns an array list containing the elements returned by the
  2231. * specified enumeration in the order they are returned by the
  2232. * enumeration. This method provides interoperatbility between
  2233. * legacy APIs that return enumerations and new APIs that require
  2234. * collections.
  2235. *
  2236. * @param e enumeration providing elements for the returned
  2237. * array list
  2238. * @return an array list containing the elements returned
  2239. * by the specified enumeration.
  2240. * @since 1.4
  2241. * @see Enumeration
  2242. * @see ArrayList
  2243. */
  2244. public static ArrayList list(Enumeration e) {
  2245. ArrayList l = new ArrayList();
  2246. while (e.hasMoreElements())
  2247. l.add(e.nextElement());
  2248. return l;
  2249. }
  2250. /**
  2251. * Returns true if the specified arguments are equal, or both null.
  2252. */
  2253. private static boolean eq(Object o1, Object o2) {
  2254. return (o1==null ? o2==null : o1.equals(o2));
  2255. }
  2256. }