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