1. /*
  2. * @(#)Collections.java 1.35 01/11/29
  3. *
  4. * Copyright 2002 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.<p>
  14. *
  15. * The documentation for the polymorphic algorithms contained in this class
  16. * generally includes a brief description of the <i>implementation</i>. Such
  17. * descriptions should be regarded as <i>implementation notes</i>, rather than
  18. * parts of the <i>specification</i>. Implementors should feel free to
  19. * substitute other algorithms, so long as the specification itself is adhered
  20. * to. (For example, the algorithm used by <tt>sort</tt> does not have to be
  21. * a mergesort, but it does have to be <i>stable</i>.)
  22. *
  23. * @author Josh Bloch
  24. * @version 1.35 11/29/01
  25. * @see Collection
  26. * @see Set
  27. * @see List
  28. * @see Map
  29. * @since JDK1.2
  30. */
  31. public class Collections {
  32. // Suppresses default constructor, ensuring non-instantiability.
  33. private Collections() {
  34. }
  35. // Algorithms
  36. /**
  37. * Sorts the specified list into ascending order, according to the
  38. * <i>natural ordering</i> of its elements. All elements in the list must
  39. * implement the <tt>Comparable</tt> interface. Furthermore, all elements
  40. * in the list must be <i>mutually comparable</i> (that is,
  41. * <tt>e1.compareTo(e2)</tt> must not throw a <tt>ClassCastException</tt>
  42. * for any elements <tt>e1</tt> and <tt>e2</tt> in the list).<p>
  43. *
  44. * This sort is guaranteed to be <i>stable</i>: equal elements will
  45. * not be reordered as a result of the sort.<p>
  46. *
  47. * The specified list must be modifiable, but need not be resizable.<p>
  48. *
  49. * The sorting algorithm is a modified mergesort (in which the merge is
  50. * omitted if the highest element in the low sublist is less than the
  51. * lowest element in the high sublist). This algorithm offers guaranteed
  52. * n log(n) performance, and can approach linear performance on nearly
  53. * sorted lists.<p>
  54. *
  55. * This implementation dumps the specified list into an array, sorts
  56. * the array, and iterates over the list resetting each element
  57. * from the corresponding position in the array. This avoids the
  58. * n<sup>2</sup> log(n) performance that would result from attempting
  59. * to sort a linked list in place.
  60. *
  61. * @param list the list to be sorted.
  62. * @throws ClassCastException if the list contains elements that are not
  63. * <i>mutually comparable</i> (for example, strings and integers).
  64. * @throws UnsupportedOperationException if the specified list's
  65. * list-iterator does not support the <tt>set</tt> operation.
  66. * @see Comparable
  67. */
  68. public static void sort(List list) {
  69. Object a[] = list.toArray();
  70. Arrays.sort(a);
  71. ListIterator i = list.listIterator();
  72. for (int j=0; j<a.length; j++) {
  73. i.next();
  74. i.set(a[j]);
  75. }
  76. }
  77. /**
  78. * Sorts the specified list according to the order induced by the
  79. * specified comparator. All elements in the list must be <i>mutually
  80. * comparable</i> using the specified comparator (that is,
  81. * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt>
  82. * for any elements <tt>e1</tt> and <tt>e2</tt> in the list).<p>
  83. *
  84. * This sort is guaranteed to be <i>stable</i>: equal elements will
  85. * not be reordered as a result of the sort.<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, and can approach linear performance on nearly
  91. * sorted lists.<p>
  92. *
  93. * The specified list must be modifiable, but need not be resizable.
  94. * This implementation dumps the specified list into an array, sorts
  95. * the array, and iterates over the list resetting each element
  96. * from the corresponding position in the array. This avoids the
  97. * n<sup>2</sup> log(n) performance that would result from attempting
  98. * to sort a linked list in place.
  99. *
  100. * @param list the list to be sorted.
  101. * @param c the comparator to determine the order of the array.
  102. * @throws ClassCastException if the list contains elements that are not
  103. * <i>mutually comparable</i> using the specified comparator.
  104. * @throws UnsupportedOperationException if the specified list's
  105. * list-iterator does not support the <tt>set</tt> operation.
  106. * @see Comparator
  107. */
  108. public static void sort(List list, Comparator c) {
  109. Object a[] = list.toArray();
  110. Arrays.sort(a, c);
  111. ListIterator i = list.listIterator();
  112. for (int j=0; j<a.length; j++) {
  113. i.next();
  114. i.set(a[j]);
  115. }
  116. }
  117. /**
  118. * Searches the specified list for the specified object using the binary
  119. * search algorithm. The list must be sorted into ascending order
  120. * according to the <i>natural ordering</i> of its elements (as by the
  121. * <tt>sort(List)</tt> method, above) prior to making this call. If it is
  122. * not sorted, the results are undefined. If the list contains multiple
  123. * elements equal to the specified object, there is no guarantee which one
  124. * will be found.<p>
  125. *
  126. * This method runs in log(n) time for a "random access" list (which
  127. * provides near-constant-time positional access). It may
  128. * run in n log(n) time if it is called on a "sequential access" list
  129. * (which provides linear-time positional access).</p>
  130. *
  131. * If the specified list implements the <tt>AbstracSequentialList</tt>
  132. * interface, this method will do a sequential search instead of a binary
  133. * search; this offers linear performance instead of n log(n) performance
  134. * if this method is called on a <tt>LinkedList</tt> object.
  135. *
  136. * @param list the list to be searched.
  137. * @param key the key to be searched for.
  138. * @return index of the search key, if it is contained in the list;
  139. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  140. * <i>insertion point</i> is defined as the point at which the
  141. * key would be inserted into the list: the index of the first
  142. * element greater than the key, or <tt>list.size()</tt>, if all
  143. * elements in the list are less than the specified key. Note
  144. * that this guarantees that the return value will be >= 0 if
  145. * and only if the key is found.
  146. * @throws ClassCastException if the list contains elements that are not
  147. * <i>mutually comparable</i> (for example, strings and
  148. * integers), or the search key in not mutually comparable
  149. * with the elements of the list.
  150. * @see Comparable
  151. * @see #sort(List)
  152. */
  153. public static int binarySearch(List list, Object key) {
  154. // Do a sequential search if appropriate
  155. if (list instanceof AbstractSequentialList) {
  156. ListIterator i = list.listIterator();
  157. while (i.hasNext()) {
  158. int cmp = ((Comparable)(i.next())).compareTo(key);
  159. if (cmp == 0)
  160. return i.previousIndex();
  161. else if (cmp > 0)
  162. return -i.nextIndex(); // key not found.
  163. }
  164. return -i.nextIndex()-1; // key not found, list exhausted
  165. }
  166. // Otherwise, do a binary search
  167. int low = 0;
  168. int high = list.size()-1;
  169. while (low <= high) {
  170. int mid =(low + high)/2;
  171. Object midVal = list.get(mid);
  172. int cmp = ((Comparable)midVal).compareTo(key);
  173. if (cmp < 0)
  174. low = mid + 1;
  175. else if (cmp > 0)
  176. high = mid - 1;
  177. else
  178. return mid; // key found
  179. }
  180. return -(low + 1); // key not found
  181. }
  182. /**
  183. * Searches the specified list for the specified object using the binary
  184. * search algorithm. The list must be sorted into ascending order
  185. * according to the specified comparator (as by the <tt>Sort(List,
  186. * Comparator)</tt> method, above), prior to making this call. If it is
  187. * not sorted, the results are undefined. If the list contains multiple
  188. * elements equal to the specified object, there is no guarantee which one
  189. * will be found.<p>
  190. *
  191. * This method runs in log(n) time for a "random access" list (which
  192. * provides near-constant-time positional access). It may
  193. * run in n log(n) time if it is called on a "sequential access" list
  194. * (which provides linear-time positional access).</p>
  195. *
  196. * If the specified list implements the <tt>AbstracSequentialList</tt>
  197. * interface, this method will do a sequential search instead of a binary
  198. * search; this offers linear performance instead of n log(n) performance
  199. * if this method is called on a <tt>LinkedList</tt> object.
  200. *
  201. * @param list the list to be searched.
  202. * @param key the key to be searched for.
  203. * @param c the comparator by which the list is ordered.
  204. * @return index of the search key, if it is contained in the list;
  205. * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
  206. * <i>insertion point</i> is defined as the point at which the
  207. * key would be inserted into the list: the index of the first
  208. * element greater than the key, or <tt>list.size()</tt>, if all
  209. * elements in the list are less than the specified key. Note
  210. * that this guarantees that the return value will be >= 0 if
  211. * and only if the key is found.
  212. * @throws ClassCastException if the list contains elements that are not
  213. * <i>mutually comparable</i> using the specified comparator,
  214. * or the search key in not mutually comparable with the
  215. * elements of the list using this comparator.
  216. * @see Comparable
  217. * @see #sort(List, Comparator)
  218. */
  219. public static int binarySearch(List list, Object key, Comparator c) {
  220. // Do a sequential search if appropriate
  221. if (list instanceof AbstractSequentialList) {
  222. ListIterator i = list.listIterator();
  223. while (i.hasNext()) {
  224. int cmp = c.compare(i.next(), key);
  225. if (cmp == 0)
  226. return i.previousIndex();
  227. else if (cmp > 0)
  228. return -i.nextIndex(); // key not found.
  229. }
  230. return -i.nextIndex()-1; // key not found, list exhausted
  231. }
  232. // Otherwise, do a binary search
  233. int low = 0;
  234. int high = list.size()-1;
  235. while (low <= high) {
  236. int mid =(low + high)/2;
  237. Object midVal = list.get(mid);
  238. int cmp = c.compare(midVal, key);
  239. if (cmp < 0)
  240. low = mid + 1;
  241. else if (cmp > 0)
  242. high = mid - 1;
  243. else
  244. return mid; // key found
  245. }
  246. return -(low + 1); // key not found
  247. }
  248. /**
  249. * Reverses the order of the elements in the specified list.<p>
  250. *
  251. * This method runs in linear time.
  252. *
  253. * @param list the list whose elements are to be reversed.
  254. * @throws UnsupportedOperationException if the specified list's
  255. * list-iterator does not support the <tt>set</tt> operation.
  256. */
  257. public static void reverse(List l) {
  258. ListIterator fwd = l.listIterator(), rev = l.listIterator(l.size());
  259. for (int i=0, n=l.size()/2; i<n; i++) {
  260. Object tmp = fwd.next();
  261. fwd.set(rev.previous());
  262. rev.set(tmp);
  263. }
  264. }
  265. /**
  266. * Randomly permutes the specified list using a default source of
  267. * randomness. All permutations occur with approximately equal
  268. * likelihood.<p>
  269. *
  270. * The hedge "approximately" is used in the foregoing description because
  271. * default source of randomenss is only approximately an unbiased source
  272. * of independently chosen bits. If it were a perfect source of randomly
  273. * chosen bits, then the algorithm would choose permutations with perfect
  274. * uniformity.<p>
  275. *
  276. * This implementation traverses the list backwards, from the last element
  277. * up to the second, repeatedly swapping a randomly selected element into
  278. * the "current position". Elements are randomly selected from the
  279. * portion of the list that runs from the first element to the current
  280. * position, inclusive.<p>
  281. *
  282. * This method runs in linear time for a "random access" list (which
  283. * provides near-constant-time positional access). It may require
  284. * quadratic time for a "sequential access" list.
  285. *
  286. * @param list the list to be shuffled.
  287. * @throws UnsupportedOperationException if the specified list's
  288. * list-iterator does not support the <tt>set</tt> operation.
  289. */
  290. public static void shuffle(List list) {
  291. shuffle(list, r);
  292. }
  293. private static Random r = new Random();
  294. /**
  295. * Randomly permute the specified list using the specified source of
  296. * randomness. All permutations occur with equal likelihood
  297. * assuming that the source of randomness is fair.<p>
  298. *
  299. * This implementation traverses the list backwards, from the last element
  300. * up to the second, repeatedly swapping a randomly selected element into
  301. * the "current position". Elements are randomly selected from the
  302. * portion of the list that runs from the first element to the current
  303. * position, inclusive.<p>
  304. *
  305. * This method runs in linear time for a "random access" list (which
  306. * provides near-constant-time positional access). It may require
  307. * quadratic time for a "sequential access" list.
  308. *
  309. * @param list the list to be shuffled.
  310. * @param r the source of randomness to use to shuffle the list.
  311. * @throws UnsupportedOperationException if the specified list's
  312. * list-iterator does not support the <tt>set</tt> operation.
  313. */
  314. public static void shuffle(List list, Random rnd) {
  315. for (int i=list.size(); i>1; i--)
  316. swap(list, i-1, rnd.nextInt(i));
  317. }
  318. /**
  319. * Swaps the two specified elements in the specified list.
  320. */
  321. private static void swap(List a, int i, int j) {
  322. Object tmp = a.get(i);
  323. a.set(i, a.get(j));
  324. a.set(j, tmp);
  325. }
  326. /**
  327. * Replaces all of the elements of the specified list with the specified
  328. * element. <p>
  329. *
  330. * This method runs in linear time.
  331. *
  332. * @param list the list to be filled with the specified element.
  333. * @param o The element with which to fill the specified list.
  334. * @throws UnsupportedOperationException if the specified list's
  335. * list-iterator does not support the <tt>set</tt> operation.
  336. */
  337. public static void fill(List list, Object o) {
  338. for (ListIterator i = list.listIterator(); i.hasNext(); ) {
  339. i.next();
  340. i.set(o);
  341. }
  342. }
  343. /**
  344. * Copies all of the elements from one list into another. After the
  345. * operation, the index of each copied element in the destination list
  346. * will be identical to its index in the source list. The destination
  347. * list must be at least as long as the source list. If it is longer, the
  348. * remaining elements in the destination list are unaffected. <p>
  349. *
  350. * This method runs in linear time.
  351. *
  352. * @param dest The destination list.
  353. * @param src The source list.
  354. * @throws IndexOutOfBoundsException if the destination list is too small
  355. * to contain the entire source List.
  356. * @throws UnsupportedOperationException if the destination list's
  357. * list-iterator does not support the <tt>set</tt> operation.
  358. */
  359. public static void copy (List dest, List src) {
  360. try {
  361. for (ListIterator di=dest.listIterator(), si=src.listIterator();
  362. si.hasNext(); ) {
  363. di.next();
  364. di.set(si.next());
  365. }
  366. } catch(NoSuchElementException e) {
  367. throw new IndexOutOfBoundsException("Source does not fit in dest.");
  368. }
  369. }
  370. /**
  371. * Returns the minimum element of the given collection, according to the
  372. * <i>natural ordering</i> of its elements. All elements in the
  373. * collection must implement the <tt>Comparable</tt> interface.
  374. * Furthermore, all elements in the collection must be <i>mutually
  375. * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  376. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  377. * <tt>e2</tt> in the collection).<p>
  378. *
  379. * This method iterates over the entire collection, hence it requires
  380. * time proportional to the size of the collection.
  381. *
  382. * @param coll the collection whose minimum element is to be determined.
  383. * @return the minimum element of the given collection, according
  384. * to the <i>natural ordering</i> of its elements.
  385. * @throws ClassCastException if the collection contains elements that are
  386. * not <i>mutually comparable</i> (for example, strings and
  387. * integers).
  388. * @throws NoSuchElementException if the collection is empty.
  389. * @see Comparable
  390. */
  391. public static Object min(Collection coll) {
  392. Iterator i = coll.iterator();
  393. Comparable candidate = (Comparable)(i.next());
  394. while (i.hasNext()) {
  395. Comparable next = (Comparable)(i.next());
  396. if (next.compareTo(candidate) < 0)
  397. candidate = next;
  398. }
  399. return candidate;
  400. }
  401. /**
  402. * Returns the minimum element of the given collection, according to the
  403. * order induced by the specified comparator. All elements in the
  404. * collection must be <i>mutually comparable</i> by the specified
  405. * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
  406. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  407. * <tt>e2</tt> in the collection).<p>
  408. *
  409. * This method iterates over the entire collection, hence it requires
  410. * time proportional to the size of the collection.
  411. *
  412. * @param coll the collection whose minimum element is to be determined.
  413. * @return the minimum element of the given collection, according
  414. * to the specified comparator.
  415. * @throws ClassCastException if the collection contains elements that are
  416. * not <i>mutually comparable</i> using the specified comparator.
  417. * @throws NoSuchElementException if the collection is empty.
  418. * @see Comparable
  419. */
  420. public static Object min(Collection coll, Comparator comp) {
  421. Iterator i = coll.iterator();
  422. Object candidate = i.next();
  423. while (i.hasNext()) {
  424. Object next = i.next();
  425. if (comp.compare(next, candidate) < 0)
  426. candidate = next;
  427. }
  428. return candidate;
  429. }
  430. /**
  431. * Returns the maximum element of the given collection, according to the
  432. * <i>natural ordering</i> of its elements. All elements in the
  433. * collection must implement the <tt>Comparable</tt> interface.
  434. * Furthermore, all elements in the collection must be <i>mutually
  435. * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  436. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  437. * <tt>e2</tt> in the collection).<p>
  438. *
  439. * This method iterates over the entire collection, hence it requires
  440. * time proportional to the size of the collection.
  441. *
  442. * @param coll the collection whose maximum element is to be determined.
  443. * @return the maximum element of the given collection, according
  444. * to the <i>natural ordering</i> of its elements.
  445. * @throws ClassCastException if the collection contains elements that are
  446. * not <i>mutually comparable</i> (for example, strings and
  447. * integers).
  448. * @throws NoSuchElementException if the collection is empty.
  449. * @see Comparable
  450. */
  451. public static Object max(Collection coll) {
  452. Iterator i = coll.iterator();
  453. Comparable candidate = (Comparable)(i.next());
  454. while (i.hasNext()) {
  455. Comparable next = (Comparable)(i.next());
  456. if (next.compareTo(candidate) > 0)
  457. candidate = next;
  458. }
  459. return candidate;
  460. }
  461. /**
  462. * Returns the maximum element of the given collection, according to the
  463. * order induced by the specified comparator. All elements in the
  464. * collection must be <i>mutually comparable</i> by the specified
  465. * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
  466. * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  467. * <tt>e2</tt> in the collection).<p>
  468. *
  469. * This method iterates over the entire collection, hence it requires
  470. * time proportional to the size of the collection.
  471. *
  472. * @param coll the collection whose maximum element is to be determined.
  473. * @return the maximum element of the given collection, according
  474. * to the specified comparator.
  475. * @throws ClassCastException if the collection contains elements that are
  476. * not <i>mutually comparable</i> using the specified comparator.
  477. * @throws NoSuchElementException if the collection is empty.
  478. * @see Comparable
  479. */
  480. public static Object max(Collection coll, Comparator comp) {
  481. Iterator i = coll.iterator();
  482. Object candidate = i.next();
  483. while (i.hasNext()) {
  484. Object next = i.next();
  485. if (comp.compare(next, candidate) > 0)
  486. candidate = next;
  487. }
  488. return candidate;
  489. }
  490. // Unmodifiable Wrappers
  491. /**
  492. * Returns an unmodifiable view of the specified collection. This method
  493. * allows modules to provide users with "read-only" access to internal
  494. * collections. Query operations on the returned collection "read through"
  495. * to the specified collection, and attempts to modify the returned
  496. * collection, whether direct or via its iterator, result in an
  497. * <tt>UnsupportedOperationException</tt>.<p>
  498. *
  499. * The returned collection does <i>not</i> pass the hashCode and equals
  500. * operations through to the backing collection, but relies on
  501. * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods. This
  502. * is necessary to preserve the contracts of these operations in the case
  503. * that the backing collection is a set or a list.<p>
  504. *
  505. * The returned collection will be serializable if the specified collection
  506. * is serializable.
  507. *
  508. * @param c the collection for which an unmodifiable view is to be
  509. * returned.
  510. * @return an unmodifiable view of the specified collection.
  511. */
  512. public static Collection unmodifiableCollection(Collection c) {
  513. return new UnmodifiableCollection(c);
  514. }
  515. static class UnmodifiableCollection implements Collection, Serializable {
  516. Collection c;
  517. UnmodifiableCollection(Collection c) {this.c = c;}
  518. public int size() {return c.size();}
  519. public boolean isEmpty() {return c.isEmpty();}
  520. public boolean contains(Object o) {return c.contains(o);}
  521. public Object[] toArray() {return c.toArray();}
  522. public Object[] toArray(Object[] a) {return c.toArray(a);}
  523. public Iterator iterator() {
  524. return new Iterator() {
  525. Iterator i = c.iterator();
  526. public boolean hasNext() {return i.hasNext();}
  527. public Object next() {return i.next();}
  528. public void remove() {
  529. throw new UnsupportedOperationException();
  530. }
  531. };
  532. }
  533. public boolean add(Object o){
  534. throw new UnsupportedOperationException();
  535. }
  536. public boolean remove(Object o) {
  537. throw new UnsupportedOperationException();
  538. }
  539. public boolean containsAll(Collection coll) {
  540. return c.containsAll(coll);
  541. }
  542. public boolean addAll(Collection coll) {
  543. throw new UnsupportedOperationException();
  544. }
  545. public boolean removeAll(Collection coll) {
  546. throw new UnsupportedOperationException();
  547. }
  548. public boolean retainAll(Collection coll) {
  549. throw new UnsupportedOperationException();
  550. }
  551. public void clear() {
  552. throw new UnsupportedOperationException();
  553. }
  554. }
  555. /**
  556. * Returns an unmodifiable view of the specified set. This method allows
  557. * modules to provide users with "read-only" access to internal sets.
  558. * Query operations on the returned set "read through" to the specified
  559. * set, and attempts to modify the returned set, whether direct or via its
  560. * iterator, result in an <tt>UnsupportedOperationException</tt>.<p>
  561. *
  562. * The returned set will be serializable if the specified set
  563. * is serializable.
  564. *
  565. * @param s the set for which an unmodifiable view is to be returned.
  566. * @return an unmodifiable view of the specified set.
  567. */
  568. public static Set unmodifiableSet(Set s) {
  569. return new UnmodifiableSet(s);
  570. }
  571. static class UnmodifiableSet extends UnmodifiableCollection
  572. implements Set, Serializable {
  573. UnmodifiableSet(Set s) {super(s);}
  574. public boolean equals(Object o) {return c.equals(o);}
  575. public int hashCode() {return c.hashCode();}
  576. }
  577. /**
  578. * Returns an unmodifiable view of the specified sorted set. This method
  579. * allows modules to provide users with "read-only" access to internal
  580. * sorted sets. Query operations on the returned sorted set "read
  581. * through" to the specified sorted set. Attempts to modify the returned
  582. * sorted set, whether direct, via its iterator, or via its
  583. * <tt>subSet</tt>, <tt>headSet</tt>, or <tt>tailSet</tt> views, result in
  584. * an <tt>UnsupportedOperationException</tt>.<p>
  585. *
  586. * The returned sorted set will be serializable if the specified sorted set
  587. * is serializable.
  588. *
  589. * @param s the sorted set for which an unmodifiable view is to be
  590. * returned.
  591. * @return an unmodifiable view of the specified sorted set.
  592. */
  593. public static SortedSet unmodifiableSortedSet(SortedSet s) {
  594. return new UnmodifiableSortedSet(s);
  595. }
  596. static class UnmodifiableSortedSet extends UnmodifiableSet
  597. implements SortedSet, Serializable {
  598. private SortedSet ss;
  599. UnmodifiableSortedSet(SortedSet s) {super(s); ss = s;}
  600. public Comparator comparator() {return ss.comparator();}
  601. public SortedSet subSet(Object fromElement, Object toElement) {
  602. return new UnmodifiableSortedSet(ss.subSet(fromElement,toElement));
  603. }
  604. public SortedSet headSet(Object toElement) {
  605. return new UnmodifiableSortedSet(ss.headSet(toElement));
  606. }
  607. public SortedSet tailSet(Object fromElement) {
  608. return new UnmodifiableSortedSet(ss.tailSet(fromElement));
  609. }
  610. public Object first() {return ss.first();}
  611. public Object last() {return ss.last();}
  612. }
  613. /**
  614. * Returns an unmodifiable view of the specified list. This method allows
  615. * modules to provide users with "read-only" access to internal
  616. * lists. Query operations on the returned list "read through" to the
  617. * specified list, and attempts to modify the returned list, whether
  618. * direct or via its iterator, result in an
  619. * <tt>UnsupportedOperationException</tt>.<p>
  620. *
  621. * The returned list will be serializable if the specified list
  622. * is serializable.
  623. *
  624. * @param list the list for which an unmodifiable view is to be returned.
  625. * @return an unmodifiable view of the specified list.
  626. */
  627. public static List unmodifiableList(List list) {
  628. return new UnmodifiableList(list);
  629. }
  630. static class UnmodifiableList extends UnmodifiableCollection
  631. implements List {
  632. private List list;
  633. UnmodifiableList(List list) {
  634. super(list);
  635. this.list = list;
  636. }
  637. public boolean equals(Object o) {return list.equals(o);}
  638. public int hashCode() {return list.hashCode();}
  639. public Object get(int index) {return list.get(index);}
  640. public Object set(int index, Object element) {
  641. throw new UnsupportedOperationException();
  642. }
  643. public void add(int index, Object element) {
  644. throw new UnsupportedOperationException();
  645. }
  646. public Object remove(int index) {
  647. throw new UnsupportedOperationException();
  648. }
  649. public int indexOf(Object o) {return list.indexOf(o);}
  650. public int lastIndexOf(Object o) {return list.lastIndexOf(o);}
  651. public boolean addAll(int index, Collection c) {
  652. throw new UnsupportedOperationException();
  653. }
  654. public ListIterator listIterator() {return listIterator(0);}
  655. public ListIterator listIterator(final int index) {
  656. return new ListIterator() {
  657. ListIterator i = list.listIterator(index);
  658. public boolean hasNext() {return i.hasNext();}
  659. public Object next() {return i.next();}
  660. public boolean hasPrevious() {return i.hasPrevious();}
  661. public Object previous() {return i.previous();}
  662. public int nextIndex() {return i.nextIndex();}
  663. public int previousIndex() {return i.previousIndex();}
  664. public void remove() {
  665. throw new UnsupportedOperationException();
  666. }
  667. public void set(Object o) {
  668. throw new UnsupportedOperationException();
  669. }
  670. public void add(Object o) {
  671. throw new UnsupportedOperationException();
  672. }
  673. };
  674. }
  675. public List subList(int fromIndex, int toIndex) {
  676. return new UnmodifiableList(list.subList(fromIndex, toIndex));
  677. }
  678. }
  679. /**
  680. * Returns an unmodifiable view of the specified map. This method
  681. * allows modules to provide users with "read-only" access to internal
  682. * maps. Query operations on the returned map "read through"
  683. * to the specified map, and attempts to modify the returned
  684. * map, whether direct or via its collection views, result in an
  685. * <tt>UnsupportedOperationException</tt>.<p>
  686. *
  687. * The returned map will be serializable if the specified map
  688. * is serializable.
  689. *
  690. * @param m the map for which an unmodifiable view is to be returned.
  691. * @return an unmodifiable view of the specified map.
  692. */
  693. public static Map unmodifiableMap(Map m) {
  694. return new UnmodifiableMap(m);
  695. }
  696. private static class UnmodifiableMap implements Map, Serializable {
  697. private final Map m;
  698. UnmodifiableMap(Map m) {this.m = m;}
  699. public int size() {return m.size();}
  700. public boolean isEmpty() {return m.isEmpty();}
  701. public boolean containsKey(Object key) {return m.containsKey(key);}
  702. public boolean containsValue(Object val) {return m.containsValue(val);}
  703. public Object get(Object key) {return m.get(key);}
  704. public Object put(Object key, Object value) {
  705. throw new UnsupportedOperationException();
  706. }
  707. public Object remove(Object key) {
  708. throw new UnsupportedOperationException();
  709. }
  710. public void putAll(Map t) {
  711. throw new UnsupportedOperationException();
  712. }
  713. public void clear() {
  714. throw new UnsupportedOperationException();
  715. }
  716. private transient Set keySet = null;
  717. private transient Set entrySet = null;
  718. private transient Collection values = null;
  719. public Set keySet() {
  720. if (keySet==null)
  721. keySet = unmodifiableSet(m.keySet());
  722. return keySet;
  723. }
  724. public Set entrySet() {
  725. if (entrySet==null)
  726. entrySet = new UnmodifiableEntrySet(m.entrySet());
  727. return entrySet;
  728. }
  729. public Collection values() {
  730. if (values==null)
  731. values = unmodifiableCollection(m.values());
  732. return values;
  733. }
  734. public boolean equals(Object o) {return m.equals(o);}
  735. public int hashCode() {return m.hashCode();}
  736. /**
  737. * We need this class in addition to UnmodifiableSet as
  738. * Map.Entries themselves permit modification of the backing Map
  739. * via their setValue operation. This class is subtle: there are
  740. * many possible attacks that must be thwarted.
  741. */
  742. static class UnmodifiableEntrySet extends UnmodifiableSet {
  743. UnmodifiableEntrySet(Set s) {
  744. super(s);
  745. }
  746. public Iterator iterator() {
  747. return new Iterator() {
  748. Iterator i = c.iterator();
  749. public boolean hasNext() {
  750. return i.hasNext();
  751. }
  752. public Object next() {
  753. return new UnmodifiableEntry((Map.Entry)i.next());
  754. }
  755. public void remove() {
  756. throw new UnsupportedOperationException();
  757. }
  758. };
  759. }
  760. public Object[] toArray() {
  761. Object[] a = c.toArray();
  762. for (int i=0; i<a.length; i++)
  763. a[i] = new UnmodifiableEntry((Map.Entry)a[i]);
  764. return a;
  765. }
  766. public Object[] toArray(Object a[]) {
  767. // We don't pass a to c.toArray, to avoid window of
  768. // vulnerability wherein an unscrupulous multithreaded client
  769. // could get his hands on raw (unwrapped) Entries from c.
  770. Object[] arr = c.toArray(a.length==0 ? a :
  771. (Object[])java.lang.reflect.Array.newInstance(
  772. a.getClass().getComponentType(), 0));
  773. for (int i=0; i<arr.length; i++)
  774. arr[i] = new UnmodifiableEntry((Map.Entry)arr[i]);
  775. if (arr.length > a.length)
  776. return arr;
  777. System.arraycopy(arr, 0, a, 0, arr.length);
  778. if (a.length > arr.length)
  779. a[arr.length] = null;
  780. return a;
  781. }
  782. /**
  783. * This method is overridden to protect the backing set against
  784. * an object with a nefarious equals function that senses
  785. * that the equality-candidate is Map.Entry and calls its
  786. * setValue method.
  787. */
  788. public boolean contains(Object o) {
  789. if (!(o instanceof Map.Entry))
  790. return false;
  791. return c.contains(new UnmodifiableEntry((Map.Entry)o));
  792. }
  793. /**
  794. * The next two methods are overridden to protect against
  795. * an unscrupulous List whose contains(Object o) method senses
  796. * when o is a Map.Entry, and calls o.setValue.
  797. */
  798. public boolean containsAll(Collection coll) {
  799. Iterator e = coll.iterator();
  800. while (e.hasNext())
  801. if(!contains(e.next())) // Invokes safe contains() above
  802. return false;
  803. return true;
  804. }
  805. public boolean equals(Object o) {
  806. if (o == this)
  807. return true;
  808. if (!(o instanceof Set))
  809. return false;
  810. Set s = (Set) o;
  811. if (s.size() != c.size())
  812. return false;
  813. return containsAll(s); // Invokes safe containsAll() above
  814. }
  815. /**
  816. * This "wrapper class" serves two purposes: it prevents
  817. * the client from modifying the backing Map, by short-circuiting
  818. * the setValue method, and it protects the backing Map against
  819. * an ill-behaved Map.Entry that attempts to modify another
  820. * Map Entry when asked to perform an equality check.
  821. */
  822. private static class UnmodifiableEntry implements Map.Entry {
  823. private Map.Entry e;
  824. UnmodifiableEntry(Map.Entry e) {this.e = e;}
  825. public Object getKey() {return e.getKey();}
  826. public Object getValue() {return e.getValue();}
  827. public Object setValue(Object value) {
  828. throw new UnsupportedOperationException();
  829. }
  830. public int hashCode() {return e.hashCode();}
  831. public boolean equals(Object o) {
  832. if (!(o instanceof Map.Entry))
  833. return false;
  834. Map.Entry t = (Map.Entry)o;
  835. return eq(e.getKey(), t.getKey()) &&
  836. eq(e.getValue(), t.getValue());
  837. }
  838. public String toString() {return e.toString();}
  839. }
  840. }
  841. }
  842. /**
  843. * Returns an unmodifiable view of the specified sorted map. This method
  844. * allows modules to provide users with "read-only" access to internal
  845. * sorted maps. Query operations on the returned sorted map "read through"
  846. * to the specified sorted map. Attempts to modify the returned
  847. * sorted map, whether direct, via its collection views, or via its
  848. * <tt>subMap</tt>, <tt>headMap</tt>, or <tt>tailMap</tt> views, result in
  849. * an <tt>UnsupportedOperationException</tt>.<p>
  850. *
  851. * The returned sorted map will be serializable if the specified sorted map
  852. * is serializable.
  853. *
  854. * @param m the sorted map for which an unmodifiable view is to be
  855. * returned.
  856. * @return an unmodifiable view of the specified sorted map.
  857. */
  858. public static SortedMap unmodifiableSortedMap(SortedMap m) {
  859. return new UnmodifiableSortedMap(m);
  860. }
  861. static class UnmodifiableSortedMap extends UnmodifiableMap
  862. implements SortedMap, Serializable {
  863. private SortedMap sm;
  864. UnmodifiableSortedMap(SortedMap m) {super(m); sm = m;}
  865. public Comparator comparator() {return sm.comparator();}
  866. public SortedMap subMap(Object fromKey, Object toKey) {
  867. return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
  868. }
  869. public SortedMap headMap(Object toKey) {
  870. return new UnmodifiableSortedMap(sm.headMap(toKey));
  871. }
  872. public SortedMap tailMap(Object fromKey) {
  873. return new UnmodifiableSortedMap(sm.tailMap(fromKey));
  874. }
  875. public Object firstKey() {return sm.firstKey();}
  876. public Object lastKey() {return sm.lastKey();}
  877. }
  878. // Synch Wrappers
  879. /**
  880. * Returns a synchronized (thread-safe) collection backed by the specified
  881. * collection. In order to guarantee serial access, it is critical that
  882. * <strong>all</strong> access to the backing collection is accomplished
  883. * through the returned collection.<p>
  884. *
  885. * It is imperative that the user manually synchronize on the returned
  886. * collection when iterating over it:
  887. * <pre>
  888. * Collection c = Collections.synchronizedCollection(myCollection);
  889. * ...
  890. * synchronized(c) {
  891. * Iterator i = c.iterator(); // Must be in the synchronized block
  892. * while (i.hasNext())
  893. * foo(i.next());
  894. * }
  895. * </pre>
  896. * Failure to follow this advice may result in non-deterministic behavior.
  897. *
  898. * <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt>
  899. * and <tt>equals</tt> operations through to the backing collection, but
  900. * relies on <tt>Object</tt>'s equals and hashCode methods. This is
  901. * necessary to preserve the contracts of these operations in the case
  902. * that the backing collection is a set or a list.<p>
  903. *
  904. * The returned collection will be serializable if the specified collection
  905. * is serializable.
  906. *
  907. * @param c the collection to be "wrapped" in a synchronized collection.
  908. * @return a synchronized view of the specified collection.
  909. */
  910. public static Collection synchronizedCollection(Collection c) {
  911. return new SynchronizedCollection(c);
  912. }
  913. static Collection synchronizedCollection(Collection c, Object mutex) {
  914. return new SynchronizedCollection(c, mutex);
  915. }
  916. static class SynchronizedCollection implements Collection, Serializable {
  917. Collection c; // Backing Collection
  918. Object mutex; // Object on which to synchronize
  919. SynchronizedCollection(Collection c) {
  920. this.c = c; mutex = this;
  921. }
  922. SynchronizedCollection(Collection c, Object mutex) {
  923. this.c = c; this.mutex = mutex;
  924. }
  925. public int size() {
  926. synchronized(mutex) {return c.size();}
  927. }
  928. public boolean isEmpty() {
  929. synchronized(mutex) {return c.isEmpty();}
  930. }
  931. public boolean contains(Object o) {
  932. synchronized(mutex) {return c.contains(o);}
  933. }
  934. public Object[] toArray() {
  935. synchronized(mutex) {return c.toArray();}
  936. }
  937. public Object[] toArray(Object[] a) {
  938. synchronized(mutex) {return c.toArray(a);}
  939. }
  940. public Iterator iterator() {
  941. return c.iterator(); // Must be manually synched by user!
  942. }
  943. public boolean add(Object o) {
  944. synchronized(mutex) {return c.add(o);}
  945. }
  946. public boolean remove(Object o) {
  947. synchronized(mutex) {return c.remove(o);}
  948. }
  949. public boolean containsAll(Collection coll) {
  950. synchronized(mutex) {return c.containsAll(coll);}
  951. }
  952. public boolean addAll(Collection coll) {
  953. synchronized(mutex) {return c.addAll(coll);}
  954. }
  955. public boolean removeAll(Collection coll) {
  956. synchronized(mutex) {return c.removeAll(coll);}
  957. }
  958. public boolean retainAll(Collection coll) {
  959. synchronized(mutex) {return c.retainAll(coll);}
  960. }
  961. public void clear() {
  962. synchronized(mutex) {c.clear();}
  963. }
  964. }
  965. /**
  966. * Returns a synchronized (thread-safe) set backed by the specified
  967. * set. In order to guarantee serial access, it is critical that
  968. * <strong>all</strong> access to the backing set is accomplished
  969. * through the returned set.<p>
  970. *
  971. * It is imperative that the user manually synchronize on the returned
  972. * set when iterating over it:
  973. * <pre>
  974. * Set s = Collections.synchronizedSet(new HashSet());
  975. * ...
  976. * synchronized(s) {
  977. * Iterator i = s.iterator(); // Must be in the synchronized block
  978. * while (i.hasNext())
  979. * foo(i.next());
  980. * }
  981. * </pre>
  982. * Failure to follow this advice may result in non-deterministic behavior.
  983. *
  984. * <p>The returned set will be serializable if the specified set is
  985. * serializable.
  986. *
  987. * @param s the set to be "wrapped" in a synchronized set.
  988. * @return a synchronized view of the specified set.
  989. */
  990. public static Set synchronizedSet(Set s) {
  991. return new SynchronizedSet(s);
  992. }
  993. static Set synchronizedSet(Set s, Object mutex) {
  994. return new SynchronizedSet(s, mutex);
  995. }
  996. static class SynchronizedSet extends SynchronizedCollection
  997. implements Set {
  998. SynchronizedSet(Set s) {
  999. super(s);
  1000. }
  1001. SynchronizedSet(Set s, Object mutex) {
  1002. super(s, mutex);
  1003. }
  1004. public boolean equals(Object o) {
  1005. synchronized(mutex) {return c.equals(o);}
  1006. }
  1007. public int hashCode() {
  1008. synchronized(mutex) {return c.hashCode();}
  1009. }
  1010. }
  1011. /**
  1012. * Returns a synchronized (thread-safe) sorted set backed by the specified
  1013. * sorted set. In order to guarantee serial access, it is critical that
  1014. * <strong>all</strong> access to the backing sorted set is accomplished
  1015. * through the returned sorted set (or its views).<p>
  1016. *
  1017. * It is imperative that the user manually synchronize on the returned
  1018. * sorted set when iterating over it or any of its <tt>subSet</tt>,
  1019. * <tt>headSet</tt>, or <tt>tailSet</tt> views.
  1020. * <pre>
  1021. * SortedSet s = Collections.synchronizedSortedSet(new HashSortedSet());
  1022. * ...
  1023. * synchronized(s) {
  1024. * Iterator i = s.iterator(); // Must be in the synchronized block
  1025. * while (i.hasNext())
  1026. * foo(i.next());
  1027. * }
  1028. * </pre>
  1029. * or:
  1030. * <pre>
  1031. * SortedSet s = Collections.synchronizedSortedSet(new HashSortedSet());
  1032. * SortedSet s2 = s.headSet(foo);
  1033. * ...
  1034. * synchronized(s) { // Note: s, not s2!!!
  1035. * Iterator i = s2.iterator(); // Must be in the synchronized block
  1036. * while (i.hasNext())
  1037. * foo(i.next());
  1038. * }
  1039. * </pre>
  1040. * Failure to follow this advice may result in non-deterministic behavior.
  1041. *
  1042. * <p>The returned sorted set will be serializable if the specified
  1043. * sorted set is serializable.
  1044. *
  1045. * @param s the sorted set to be "wrapped" in a synchronized sorted set.
  1046. * @return a synchronized view of the specified sorted set.
  1047. */
  1048. public static SortedSet synchronizedSortedSet(SortedSet s) {
  1049. return new SynchronizedSortedSet(s);
  1050. }
  1051. static class SynchronizedSortedSet extends SynchronizedSet
  1052. implements SortedSet
  1053. {
  1054. private SortedSet ss;
  1055. SynchronizedSortedSet(SortedSet s) {
  1056. super(s);
  1057. ss = s;
  1058. }
  1059. SynchronizedSortedSet(SortedSet s, Object mutex) {
  1060. super(s, mutex);
  1061. ss = s;
  1062. }
  1063. public Comparator comparator() {
  1064. synchronized(mutex) {return ss.comparator();}
  1065. }
  1066. public SortedSet subSet(Object fromElement, Object toElement) {
  1067. synchronized(mutex) {
  1068. return new SynchronizedSortedSet(
  1069. ss.subSet(fromElement, toElement), mutex);
  1070. }
  1071. }
  1072. public SortedSet headSet(Object toElement) {
  1073. synchronized(mutex) {
  1074. return new SynchronizedSortedSet(ss.headSet(toElement), mutex);
  1075. }
  1076. }
  1077. public SortedSet tailSet(Object fromElement) {
  1078. synchronized(mutex) {
  1079. return new SynchronizedSortedSet(ss.tailSet(fromElement),mutex);
  1080. }
  1081. }
  1082. public Object first() {
  1083. synchronized(mutex) {return ss.first();}
  1084. }
  1085. public Object last() {
  1086. synchronized(mutex) {return ss.last();}
  1087. }
  1088. }
  1089. /**
  1090. * Returns a synchronized (thread-safe) list backed by the specified
  1091. * list. In order to guarantee serial access, it is critical that
  1092. * <strong>all</strong> access to the backing list is accomplished
  1093. * through the returned list.<p>
  1094. *
  1095. * It is imperative that the user manually synchronize on the returned
  1096. * list when iterating over it:
  1097. * <pre>
  1098. * List list = Collections.synchronizedList(new ArrayList());
  1099. * ...
  1100. * synchronized(list) {
  1101. * Iterator i = list.iterator(); // Must be in synchronized block
  1102. * while (i.hasNext())
  1103. * foo(i.next());
  1104. * }
  1105. * </pre>
  1106. * Failure to follow this advice may result in non-deterministic behavior.
  1107. *
  1108. * <p>The returned list will be serializable if the specified list is
  1109. * serializable.
  1110. *
  1111. * @param list the list to be "wrapped" in a synchronized list.
  1112. * @return a synchronized view of the specified list.
  1113. */
  1114. public static List synchronizedList(List list) {
  1115. return new SynchronizedList(list);
  1116. }
  1117. static List synchronizedList(List list, Object mutex) {
  1118. return new SynchronizedList(list, mutex);
  1119. }
  1120. static class SynchronizedList extends SynchronizedCollection
  1121. implements List {
  1122. private List list;
  1123. SynchronizedList(List list) {
  1124. super(list);
  1125. this.list = list;
  1126. }
  1127. SynchronizedList(List list, Object mutex) {
  1128. super(list, mutex);
  1129. this.list = list;
  1130. }
  1131. public boolean equals(Object o) {
  1132. synchronized(mutex) {return list.equals(o);}
  1133. }
  1134. public int hashCode() {
  1135. synchronized(mutex) {return list.hashCode();}
  1136. }
  1137. public Object get(int index) {
  1138. synchronized(mutex) {return list.get(index);}
  1139. }
  1140. public Object set(int index, Object element) {
  1141. synchronized(mutex) {return list.set(index, element);}
  1142. }
  1143. public void add(int index, Object element) {
  1144. synchronized(mutex) {list.add(index, element);}
  1145. }
  1146. public Object remove(int index) {
  1147. synchronized(mutex) {return list.remove(index);}
  1148. }
  1149. public int indexOf(Object o) {
  1150. synchronized(mutex) {return list.indexOf(o);}
  1151. }
  1152. public int lastIndexOf(Object o) {
  1153. synchronized(mutex) {return list.lastIndexOf(o);}
  1154. }
  1155. public boolean addAll(int index, Collection c) {
  1156. synchronized(mutex) {return list.addAll(index, c);}
  1157. }
  1158. public ListIterator listIterator() {
  1159. return list.listIterator(); // Must be manually synched by user
  1160. }
  1161. public ListIterator listIterator(int index) {
  1162. return list.listIterator(index); // Must be manually synched by usr
  1163. }
  1164. public List subList(int fromIndex, int toIndex) {
  1165. synchronized(mutex) {
  1166. return new SynchronizedList(list.subList(fromIndex, toIndex),
  1167. mutex);
  1168. }
  1169. }
  1170. }
  1171. /**
  1172. * Returns a synchronized (thread-safe) map backed by the specified
  1173. * map. In order to guarantee serial access, it is critical that
  1174. * <strong>all</strong> access to the backing map is accomplished
  1175. * through the returned map.<p>
  1176. *
  1177. * It is imperative that the user manually synchronize on the returned
  1178. * map when iterating over any of its collection views:
  1179. * <pre>
  1180. * Map m = Collections.synchronizedMap(new HashMap());
  1181. * ...
  1182. * Set s = m.keySet(); // Needn't be in synchronized block
  1183. * ...
  1184. * synchronized(m) { // Synchronizing on m, not s!
  1185. * Iterator i = s.iterator(); // Must be in synchronized block
  1186. * while (i.hasNext())
  1187. * foo(i.next());
  1188. * }
  1189. * </pre>
  1190. * Failure to follow this advice may result in non-deterministic behavior.
  1191. *
  1192. * <p>The returned map will be serializable if the specified map is
  1193. * serializable.
  1194. *
  1195. * @param m the map to be "wrapped" in a synchronized map.
  1196. * @return a synchronized view of the specified map.
  1197. */
  1198. public static Map synchronizedMap(Map m) {
  1199. return new SynchronizedMap(m);
  1200. }
  1201. private static class SynchronizedMap implements Map, Serializable {
  1202. private Map m; // Backing Map
  1203. Object mutex; // Object on which to synchronize
  1204. SynchronizedMap(Map m) {
  1205. this.m = m; mutex = this;
  1206. }
  1207. SynchronizedMap(Map m, Object mutex) {
  1208. this.m = m; this.mutex = mutex;
  1209. }
  1210. public int size() {
  1211. synchronized(mutex) {return m.size();}
  1212. }
  1213. public boolean isEmpty(){
  1214. synchronized(mutex) {return m.isEmpty();}
  1215. }
  1216. public boolean containsKey(Object key) {
  1217. synchronized(mutex) {return m.containsKey(key);}
  1218. }
  1219. public boolean containsValue(Object value){
  1220. synchronized(mutex) {return m.containsValue(value);}
  1221. }
  1222. public Object get(Object key) {
  1223. synchronized(mutex) {return m.get(key);}
  1224. }
  1225. public Object put(Object key, Object value) {
  1226. synchronized(mutex) {return m.put(key, value);}
  1227. }
  1228. public Object remove(Object key) {
  1229. synchronized(mutex) {return m.remove(key);}
  1230. }
  1231. public void putAll(Map map) {
  1232. synchronized(mutex) {m.putAll(map);}
  1233. }
  1234. public void clear() {
  1235. synchronized(mutex) {m.clear();}
  1236. }
  1237. private transient Set keySet = null;
  1238. private transient Set entrySet = null;
  1239. private transient Collection values = null;
  1240. public Set keySet() {
  1241. synchronized(mutex) {
  1242. if (keySet==null)
  1243. keySet = new SynchronizedSet(m.keySet(), this);
  1244. return keySet;
  1245. }
  1246. }
  1247. public Set entrySet() {
  1248. synchronized(mutex) {
  1249. if (entrySet==null)
  1250. entrySet = new SynchronizedSet(m.entrySet(), this);
  1251. return entrySet;
  1252. }
  1253. }
  1254. public Collection values() {
  1255. synchronized(mutex) {
  1256. if (values==null)
  1257. values = new SynchronizedCollection(m.values(), this);
  1258. return values;
  1259. }
  1260. }
  1261. public boolean equals(Object o) {
  1262. synchronized(mutex) {return m.equals(o);}
  1263. }
  1264. public int hashCode() {
  1265. synchronized(mutex) {return m.hashCode();}
  1266. }
  1267. }
  1268. /**
  1269. * Returns a synchronized (thread-safe) sorted map backed by the specified
  1270. * sorted map. In order to guarantee serial access, it is critical that
  1271. * <strong>all</strong> access to the backing sorted map is accomplished
  1272. * through the returned sorted map (or its views).<p>
  1273. *
  1274. * It is imperative that the user manually synchronize on the returned
  1275. * sorted map when iterating over any of its collection views, or the
  1276. * collections views of any of its <tt>subMap</tt>, <tt>headMap</tt> or
  1277. * <tt>tailMap</tt> views.
  1278. * <pre>
  1279. * SortedMap m = Collections.synchronizedSortedMap(new HashSortedMap());
  1280. * ...
  1281. * Set s = m.keySet(); // Needn't be in synchronized block
  1282. * ...
  1283. * synchronized(m) { // Synchronizing on m, not s!
  1284. * Iterator i = s.iterator(); // Must be in synchronized block
  1285. * while (i.hasNext())
  1286. * foo(i.next());
  1287. * }
  1288. * </pre>
  1289. * or:
  1290. * <pre>
  1291. * SortedMap m = Collections.synchronizedSortedMap(new HashSortedMap());
  1292. * SortedMap m2 = m.subMap(foo, bar);
  1293. * ...
  1294. * Set s2 = m2.keySet(); // Needn't be in synchronized block
  1295. * ...
  1296. * synchronized(m) { // Synchronizing on m, not m2 or s2!
  1297. * Iterator i = s.iterator(); // Must be in synchronized block
  1298. * while (i.hasNext())
  1299. * foo(i.next());
  1300. * }
  1301. * </pre>
  1302. * Failure to follow this advice may result in non-deterministic behavior.
  1303. *
  1304. * <p>The returned sorted map will be serializable if the specified
  1305. * sorted map is serializable.
  1306. *
  1307. * @param m the sorted map to be "wrapped" in a synchronized sorted map.
  1308. * @return a synchronized view of the specified sorted map.
  1309. */
  1310. public static SortedMap synchronizedSortedMap(SortedMap m) {
  1311. return new SynchronizedSortedMap(m);
  1312. }
  1313. static class SynchronizedSortedMap extends SynchronizedMap
  1314. implements SortedMap
  1315. {
  1316. private SortedMap sm;
  1317. SynchronizedSortedMap(SortedMap m) {
  1318. super(m);
  1319. sm = m;
  1320. }
  1321. SynchronizedSortedMap(SortedMap m, Object mutex) {
  1322. super(m, mutex);
  1323. sm = m;
  1324. }
  1325. public Comparator comparator() {
  1326. synchronized(mutex) {return sm.comparator();}
  1327. }
  1328. public SortedMap subMap(Object fromKey, Object toKey) {
  1329. synchronized(mutex) {
  1330. return new SynchronizedSortedMap(
  1331. sm.subMap(fromKey, toKey), mutex);
  1332. }
  1333. }
  1334. public SortedMap headMap(Object toKey) {
  1335. synchronized(mutex) {
  1336. return new SynchronizedSortedMap(sm.headMap(toKey), mutex);
  1337. }
  1338. }
  1339. public SortedMap tailMap(Object fromKey) {
  1340. synchronized(mutex) {
  1341. return new SynchronizedSortedMap(sm.tailMap(fromKey),mutex);
  1342. }
  1343. }
  1344. public Object firstKey() {
  1345. synchronized(mutex) {return sm.firstKey();}
  1346. }
  1347. public Object lastKey() {
  1348. synchronized(mutex) {return sm.lastKey();}
  1349. }
  1350. }
  1351. // Miscellaneous
  1352. /**
  1353. * The empty set (immutable). This set is serializable.
  1354. */
  1355. public static final Set EMPTY_SET = new EmptySet();
  1356. private static class EmptySet extends AbstractSet implements Serializable {
  1357. public Iterator iterator() {
  1358. return new Iterator() {
  1359. public boolean hasNext() {
  1360. return false;
  1361. }
  1362. public Object next() {
  1363. throw new NoSuchElementException();
  1364. }
  1365. public void remove() {
  1366. throw new UnsupportedOperationException();
  1367. }
  1368. };
  1369. }
  1370. public int size() {return 0;}
  1371. public boolean contains(Object obj) {return false;}
  1372. }
  1373. /**
  1374. * The empty list (immutable). This list is serializable.
  1375. */
  1376. public static final List EMPTY_LIST = new EmptyList();
  1377. private static class EmptyList extends AbstractList
  1378. implements Serializable {
  1379. public int size() {return 0;}
  1380. public boolean contains(Object obj) {return false;}
  1381. public Object get(int index) {
  1382. throw new IndexOutOfBoundsException("Index: "+index);
  1383. }
  1384. }
  1385. /**
  1386. * Returns an immutable set containing only the specified object.
  1387. * The returned set is serializable.
  1388. *
  1389. * @return an immutable set containing only the specified object.
  1390. */
  1391. public static Set singleton(Object o) {
  1392. return new SingletonSet(o);
  1393. }
  1394. private static class SingletonSet extends AbstractSet
  1395. implements Serializable
  1396. {
  1397. private Object element;
  1398. SingletonSet(Object o) {element = o;}
  1399. public Iterator iterator() {
  1400. return new Iterator() {
  1401. private boolean hasNext = true;
  1402. public boolean hasNext() {
  1403. return hasNext;
  1404. }
  1405. public Object next() {
  1406. if (hasNext) {
  1407. hasNext = false;
  1408. return element;
  1409. }
  1410. throw new NoSuchElementException();
  1411. }
  1412. public void remove() {
  1413. throw new UnsupportedOperationException();
  1414. }
  1415. };
  1416. }
  1417. public int size() {return 1;}
  1418. public boolean contains(Object o) {return eq(o, element);}
  1419. }
  1420. /**
  1421. * Returns an immutable list consisting of <tt>n</tt> copies of the
  1422. * specified object. The newly allocated data object is tiny (it contains
  1423. * a single reference to the data object). This method is useful in
  1424. * combination with the <tt>List.addAll</tt> method to grow lists.
  1425. * The returned list is serializable.
  1426. *
  1427. * @param n the number of elements in the returned list.
  1428. * @param o the element to appear repeatedly in the returned list.
  1429. * @return an immutable list consisting of <tt>n</tt> copies of the
  1430. * specified object.
  1431. * @throws IllegalArgumentException if n < 0.
  1432. * @see List#addAll(Collection)
  1433. * @see List#addAll(int, Collection)
  1434. */
  1435. public static List nCopies(int n, Object o) {
  1436. return new CopiesList(n, o);
  1437. }
  1438. private static class CopiesList extends AbstractList
  1439. implements Serializable
  1440. {
  1441. int n;
  1442. Object element;
  1443. CopiesList(int n, Object o) {
  1444. if (n < 0)
  1445. throw new IllegalArgumentException("List length = " + n);
  1446. this.n = n;
  1447. element = o;
  1448. }
  1449. public int size() {
  1450. return n;
  1451. }
  1452. public boolean contains(Object obj) {
  1453. return n != 0 && eq(obj, element);
  1454. }
  1455. public Object get(int index) {
  1456. if (index<0 || index>=n)
  1457. throw new IndexOutOfBoundsException("Index: "+index+
  1458. ", Size: "+n);
  1459. return element;
  1460. }
  1461. }
  1462. /**
  1463. * Returns a comparator that imposes the reverse of the <i>natural
  1464. * ordering</i> on a collection of objects that implement the
  1465. * <tt>Comparable</tt> interface. (The natural ordering is the ordering
  1466. * imposed by the objects' own <tt>compareTo</tt> method.) This enables a
  1467. * simple idiom for sorting (or maintaining) collections (or arrays) of
  1468. * objects that implement the <tt>Comparable</tt> interface in
  1469. * reverse-natural-order. For example, suppose a is an array of
  1470. * strings. Then: <pre>
  1471. * Arrays.sort(a, Collections.reverseOrder());
  1472. * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
  1473. *
  1474. * The returned comparator is serializable.
  1475. *
  1476. * @return a comparator that imposes the reverse of the <i>natural
  1477. * ordering</i> on a collection of objects that implement
  1478. * the <tt>Comparable</tt> interface.
  1479. * @see Comparable
  1480. */
  1481. public static Comparator reverseOrder() {
  1482. return REVERSE_ORDER;
  1483. }
  1484. private static final Comparator REVERSE_ORDER = new ReverseComparator();
  1485. private static class ReverseComparator implements Comparator,Serializable {
  1486. public int compare(Object o1, Object o2) {
  1487. Comparable c1 = (Comparable)o1;
  1488. Comparable c2 = (Comparable)o2;
  1489. return -c1.compareTo(c2);
  1490. }
  1491. }
  1492. /**
  1493. * Returns an enumeration over the specified collection. This provides
  1494. * interoperatbility with legacy APIs that require an enumeration
  1495. * as input.
  1496. *
  1497. * @param c the collection for which an enumeration is to be returned.
  1498. * @return an enumeration over the specified collection.
  1499. */
  1500. public static Enumeration enumeration(final Collection c) {
  1501. return new Enumeration() {
  1502. Iterator i = c.iterator();
  1503. public boolean hasMoreElements() {
  1504. return i.hasNext();
  1505. }
  1506. public Object nextElement() {
  1507. return i.next();
  1508. }
  1509. };
  1510. }
  1511. /**
  1512. * Returns true if the specified arguments are equal, or both null.
  1513. */
  1514. private static boolean eq(Object o1, Object o2) {
  1515. return (o1==null ? o2==null : o1.equals(o2));
  1516. }
  1517. }