| GNU Classpath (0.95) | |
| Frames | No Frames |
1: /* Collections.java -- Utility class with methods to operate on collections 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.util; 41: 42: import java.io.Serializable; 43: 44: /** 45: * Utility class consisting of static methods that operate on, or return 46: * Collections. Contains methods to sort, search, reverse, fill and shuffle 47: * Collections, methods to facilitate interoperability with legacy APIs that 48: * are unaware of collections, a method to return a list which consists of 49: * multiple copies of one element, and methods which "wrap" collections to give 50: * them extra properties, such as thread-safety and unmodifiability. 51: * <p> 52: * 53: * All methods which take a collection throw a {@link NullPointerException} if 54: * that collection is null. Algorithms which can change a collection may, but 55: * are not required, to throw the {@link UnsupportedOperationException} that 56: * the underlying collection would throw during an attempt at modification. 57: * For example, 58: * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code> 59: * does not throw a exception, even though addAll is an unsupported operation 60: * on a singleton; the reason for this is that addAll did not attempt to 61: * modify the set. 62: * 63: * @author Original author unknown 64: * @author Eric Blake (ebb9@email.byu.edu) 65: * @author Tom Tromey (tromey@redhat.com) 66: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 67: * @see Collection 68: * @see Set 69: * @see List 70: * @see Map 71: * @see Arrays 72: * @since 1.2 73: * @status updated to 1.5 74: */ 75: public class Collections 76: { 77: /** 78: * Constant used to decide cutoff for when a non-RandomAccess list should 79: * be treated as sequential-access. Basically, quadratic behavior is 80: * acceptable for small lists when the overhead is so small in the first 81: * place. I arbitrarily set it to 16, so it may need some tuning. 82: */ 83: private static final int LARGE_LIST_SIZE = 16; 84: 85: /** 86: * Determines if a list should be treated as a sequential-access one. 87: * Rather than the old method of JDK 1.3 of assuming only instanceof 88: * AbstractSequentialList should be sequential, this uses the new method 89: * of JDK 1.4 of assuming anything that does NOT implement RandomAccess 90: * and exceeds a large (unspecified) size should be sequential. 91: * 92: * @param l the list to check 93: * @return <code>true</code> if it should be treated as sequential-access 94: */ 95: private static boolean isSequential(List<?> l) 96: { 97: return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE; 98: } 99: 100: /** 101: * This class is non-instantiable. 102: */ 103: private Collections() 104: { 105: } 106: 107: /** 108: * An immutable, serializable, empty Set. 109: * @see Serializable 110: */ 111: public static final Set EMPTY_SET = new EmptySet(); 112: 113: /** 114: * Returns an immutable, serializable parameterized empty set. 115: * Unlike the constant <code>EMPTY_SET</code>, the set returned by 116: * this method is type-safe. 117: * 118: * @return an empty parameterized set. 119: * @since 1.5 120: */ 121: public static final <T> Set<T> emptySet() 122: { 123: /* FIXME: Could this be optimized? */ 124: return new EmptySet<T>(); 125: } 126: 127: /** 128: * The implementation of {@link #EMPTY_SET}. This class name is required 129: * for compatibility with Sun's JDK serializability. 130: * 131: * @author Eric Blake (ebb9@email.byu.edu) 132: */ 133: private static final class EmptySet<T> extends AbstractSet<T> 134: implements Serializable 135: { 136: /** 137: * Compatible with JDK 1.4. 138: */ 139: private static final long serialVersionUID = 1582296315990362920L; 140: 141: /** 142: * A private constructor adds overhead. 143: */ 144: EmptySet() 145: { 146: } 147: 148: /** 149: * The size: always 0! 150: * @return 0. 151: */ 152: public int size() 153: { 154: return 0; 155: } 156: 157: /** 158: * Returns an iterator that does not iterate. 159: * @return A non-iterating iterator. 160: */ 161: // This is really cheating! I think it's perfectly valid, though. 162: public Iterator<T> iterator() 163: { 164: return (Iterator<T>) EMPTY_LIST.iterator(); 165: } 166: 167: // The remaining methods are optional, but provide a performance 168: // advantage by not allocating unnecessary iterators in AbstractSet. 169: /** 170: * The empty set never contains anything. 171: * @param o The object to search for. 172: * @return <code>false</code>. 173: */ 174: public boolean contains(Object o) 175: { 176: return false; 177: } 178: 179: /** 180: * This is true only if the given collection is also empty. 181: * @param c The collection of objects which are to be compared 182: * against the members of this set. 183: * @return <code>true</code> if c is empty. 184: */ 185: public boolean containsAll(Collection<?> c) 186: { 187: return c.isEmpty(); 188: } 189: 190: /** 191: * Equal only if the other set is empty. 192: * @param o The object to compare with this set. 193: * @return <code>true</code> if o is an empty instance of <code>Set</code>. 194: */ 195: public boolean equals(Object o) 196: { 197: return o instanceof Set && ((Set) o).isEmpty(); 198: } 199: 200: /** 201: * The hashcode is always 0. 202: * @return 0. 203: */ 204: public int hashCode() 205: { 206: return 0; 207: } 208: 209: /** 210: * Always succeeds with a <code>false</code> result. 211: * @param o The object to remove. 212: * @return <code>false</code>. 213: */ 214: public boolean remove(Object o) 215: { 216: return false; 217: } 218: 219: /** 220: * Always succeeds with a <code>false</code> result. 221: * @param c The collection of objects which should 222: * all be removed from this set. 223: * @return <code>false</code>. 224: */ 225: public boolean removeAll(Collection<?> c) 226: { 227: return false; 228: } 229: 230: /** 231: * Always succeeds with a <code>false</code> result. 232: * @param c The collection of objects which should 233: * all be retained within this set. 234: * @return <code>false</code>. 235: */ 236: public boolean retainAll(Collection<?> c) 237: { 238: return false; 239: } 240: 241: /** 242: * The array is always empty. 243: * @return A new array with a size of 0. 244: */ 245: public Object[] toArray() 246: { 247: return new Object[0]; 248: } 249: 250: /** 251: * We don't even need to use reflection! 252: * @param a An existing array, which can be empty. 253: * @return The original array with any existing 254: * initial element set to null. 255: */ 256: public <E> E[] toArray(E[] a) 257: { 258: if (a.length > 0) 259: a[0] = null; 260: return a; 261: } 262: 263: /** 264: * The string never changes. 265: * 266: * @return the string "[]". 267: */ 268: public String toString() 269: { 270: return "[]"; 271: } 272: } // class EmptySet 273: 274: /** 275: * An immutable, serializable, empty List, which implements RandomAccess. 276: * @see Serializable 277: * @see RandomAccess 278: */ 279: public static final List EMPTY_LIST = new EmptyList(); 280: 281: /** 282: * Returns an immutable, serializable parameterized empty list. 283: * Unlike the constant <code>EMPTY_LIST</code>, the list returned by 284: * this method is type-safe. 285: * 286: * @return an empty parameterized list. 287: * @since 1.5 288: */ 289: public static final <T> List<T> emptyList() 290: { 291: /* FIXME: Could this be optimized? */ 292: return new EmptyList<T>(); 293: } 294: 295: /** 296: * The implementation of {@link #EMPTY_LIST}. This class name is required 297: * for compatibility with Sun's JDK serializability. 298: * 299: * @author Eric Blake (ebb9@email.byu.edu) 300: */ 301: private static final class EmptyList<T> extends AbstractList<T> 302: implements Serializable, RandomAccess 303: { 304: /** 305: * Compatible with JDK 1.4. 306: */ 307: private static final long serialVersionUID = 8842843931221139166L; 308: 309: /** 310: * A private constructor adds overhead. 311: */ 312: EmptyList() 313: { 314: } 315: 316: /** 317: * The size is always 0. 318: * @return 0. 319: */ 320: public int size() 321: { 322: return 0; 323: } 324: 325: /** 326: * No matter the index, it is out of bounds. This 327: * method never returns, throwing an exception instead. 328: * 329: * @param index The index of the element to retrieve. 330: * @return the object at the specified index. 331: * @throws IndexOutOfBoundsException as any given index 332: * is outside the bounds of an empty array. 333: */ 334: public T get(int index) 335: { 336: throw new IndexOutOfBoundsException(); 337: } 338: 339: // The remaining methods are optional, but provide a performance 340: // advantage by not allocating unnecessary iterators in AbstractList. 341: /** 342: * Never contains anything. 343: * @param o The object to search for. 344: * @return <code>false</code>. 345: */ 346: public boolean contains(Object o) 347: { 348: return false; 349: } 350: 351: /** 352: * This is true only if the given collection is also empty. 353: * @param c The collection of objects, which should be compared 354: * against the members of this list. 355: * @return <code>true</code> if c is also empty. 356: */ 357: public boolean containsAll(Collection<?> c) 358: { 359: return c.isEmpty(); 360: } 361: 362: /** 363: * Equal only if the other list is empty. 364: * @param o The object to compare against this list. 365: * @return <code>true</code> if o is also an empty instance of 366: * <code>List</code>. 367: */ 368: public boolean equals(Object o) 369: { 370: return o instanceof List && ((List) o).isEmpty(); 371: } 372: 373: /** 374: * The hashcode is always 1. 375: * @return 1. 376: */ 377: public int hashCode() 378: { 379: return 1; 380: } 381: 382: /** 383: * Returns -1. 384: * @param o The object to search for. 385: * @return -1. 386: */ 387: public int indexOf(Object o) 388: { 389: return -1; 390: } 391: 392: /** 393: * Returns -1. 394: * @param o The object to search for. 395: * @return -1. 396: */ 397: public int lastIndexOf(Object o) 398: { 399: return -1; 400: } 401: 402: /** 403: * Always succeeds with <code>false</code> result. 404: * @param o The object to remove. 405: * @return -1. 406: */ 407: public boolean remove(Object o) 408: { 409: return false; 410: } 411: 412: /** 413: * Always succeeds with <code>false</code> result. 414: * @param c The collection of objects which should 415: * all be removed from this list. 416: * @return <code>false</code>. 417: */ 418: public boolean removeAll(Collection<?> c) 419: { 420: return false; 421: } 422: 423: /** 424: * Always succeeds with <code>false</code> result. 425: * @param c The collection of objects which should 426: * all be retained within this list. 427: * @return <code>false</code>. 428: */ 429: public boolean retainAll(Collection<?> c) 430: { 431: return false; 432: } 433: 434: /** 435: * The array is always empty. 436: * @return A new array with a size of 0. 437: */ 438: public Object[] toArray() 439: { 440: return new Object[0]; 441: } 442: 443: /** 444: * We don't even need to use reflection! 445: * @param a An existing array, which can be empty. 446: * @return The original array with any existing 447: * initial element set to null. 448: */ 449: public <E> E[] toArray(E[] a) 450: { 451: if (a.length > 0) 452: a[0] = null; 453: return a; 454: } 455: 456: /** 457: * The string never changes. 458: * 459: * @return the string "[]". 460: */ 461: public String toString() 462: { 463: return "[]"; 464: } 465: } // class EmptyList 466: 467: /** 468: * An immutable, serializable, empty Map. 469: * @see Serializable 470: */ 471: public static final Map EMPTY_MAP = new EmptyMap(); 472: 473: /** 474: * Returns an immutable, serializable parameterized empty map. 475: * Unlike the constant <code>EMPTY_MAP</code>, the map returned by 476: * this method is type-safe. 477: * 478: * @return an empty parameterized map. 479: * @since 1.5 480: */ 481: public static final <K,V> Map<K,V> emptyMap() 482: { 483: /* FIXME: Could this be optimized? */ 484: return new EmptyMap<K,V>(); 485: } 486: 487: /** 488: * The implementation of {@link #EMPTY_MAP}. This class name is required 489: * for compatibility with Sun's JDK serializability. 490: * 491: * @author Eric Blake (ebb9@email.byu.edu) 492: */ 493: private static final class EmptyMap<K, V> extends AbstractMap<K, V> 494: implements Serializable 495: { 496: /** 497: * Compatible with JDK 1.4. 498: */ 499: private static final long serialVersionUID = 6428348081105594320L; 500: 501: /** 502: * A private constructor adds overhead. 503: */ 504: EmptyMap() 505: { 506: } 507: 508: /** 509: * There are no entries. 510: * @return The empty set. 511: */ 512: public Set<Map.Entry<K, V>> entrySet() 513: { 514: return EMPTY_SET; 515: } 516: 517: // The remaining methods are optional, but provide a performance 518: // advantage by not allocating unnecessary iterators in AbstractMap. 519: /** 520: * No entries! 521: * @param key The key to search for. 522: * @return <code>false</code>. 523: */ 524: public boolean containsKey(Object key) 525: { 526: return false; 527: } 528: 529: /** 530: * No entries! 531: * @param value The value to search for. 532: * @return <code>false</code>. 533: */ 534: public boolean containsValue(Object value) 535: { 536: return false; 537: } 538: 539: /** 540: * Equal to all empty maps. 541: * @param o The object o to compare against this map. 542: * @return <code>true</code> if o is also an empty instance of 543: * <code>Map</code>. 544: */ 545: public boolean equals(Object o) 546: { 547: return o instanceof Map && ((Map) o).isEmpty(); 548: } 549: 550: /** 551: * No mappings, so this returns null. 552: * @param o The key of the object to retrieve. 553: * @return null. 554: */ 555: public V get(Object o) 556: { 557: return null; 558: } 559: 560: /** 561: * The hashcode is always 0. 562: * @return 0. 563: */ 564: public int hashCode() 565: { 566: return 0; 567: } 568: 569: /** 570: * No entries. 571: * @return The empty set. 572: */ 573: public Set<K> keySet() 574: { 575: return EMPTY_SET; 576: } 577: 578: /** 579: * Remove always succeeds, with null result. 580: * @param o The key of the mapping to remove. 581: * @return null, as there is never a mapping for o. 582: */ 583: public V remove(Object o) 584: { 585: return null; 586: } 587: 588: /** 589: * Size is always 0. 590: * @return 0. 591: */ 592: public int size() 593: { 594: return 0; 595: } 596: 597: /** 598: * No entries. Technically, EMPTY_SET, while more specific than a general 599: * Collection, will work. Besides, that's what the JDK uses! 600: * @return The empty set. 601: */ 602: public Collection<V> values() 603: { 604: return EMPTY_SET; 605: } 606: 607: /** 608: * The string never changes. 609: * 610: * @return the string "[]". 611: */ 612: public String toString() 613: { 614: return "[]"; 615: } 616: } // class EmptyMap 617: 618: 619: /** 620: * Compare two objects with or without a Comparator. If c is null, uses the 621: * natural ordering. Slightly slower than doing it inline if the JVM isn't 622: * clever, but worth it for removing a duplicate of the search code. 623: * Note: This code is also used in Arrays (for sort as well as search). 624: */ 625: static final <T> int compare(T o1, T o2, Comparator<? super T> c) 626: { 627: return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2); 628: } 629: 630: /** 631: * Perform a binary search of a List for a key, using the natural ordering of 632: * the elements. The list must be sorted (as by the sort() method) - if it is 633: * not, the behavior of this method is undefined, and may be an infinite 634: * loop. Further, the key must be comparable with every item in the list. If 635: * the list contains the key more than once, any one of them may be found. 636: * <p> 637: * 638: * This algorithm behaves in log(n) time for {@link RandomAccess} lists, 639: * and uses a linear search with O(n) link traversals and log(n) comparisons 640: * with {@link AbstractSequentialList} lists. Note: although the 641: * specification allows for an infinite loop if the list is unsorted, it will 642: * not happen in this (Classpath) implementation. 643: * 644: * @param l the list to search (must be sorted) 645: * @param key the value to search for 646: * @return the index at which the key was found, or -n-1 if it was not 647: * found, where n is the index of the first value higher than key or 648: * a.length if there is no such value 649: * @throws ClassCastException if key could not be compared with one of the 650: * elements of l 651: * @throws NullPointerException if a null element has compareTo called 652: * @see #sort(List) 653: */ 654: public static <T> int binarySearch(List<? extends Comparable<? super T>> l, 655: T key) 656: { 657: return binarySearch(l, key, null); 658: } 659: 660: /** 661: * Perform a binary search of a List for a key, using a supplied Comparator. 662: * The list must be sorted (as by the sort() method with the same Comparator) 663: * - if it is not, the behavior of this method is undefined, and may be an 664: * infinite loop. Further, the key must be comparable with every item in the 665: * list. If the list contains the key more than once, any one of them may be 666: * found. If the comparator is null, the elements' natural ordering is used. 667: * <p> 668: * 669: * This algorithm behaves in log(n) time for {@link RandomAccess} lists, 670: * and uses a linear search with O(n) link traversals and log(n) comparisons 671: * with {@link AbstractSequentialList} lists. Note: although the 672: * specification allows for an infinite loop if the list is unsorted, it will 673: * not happen in this (Classpath) implementation. 674: * 675: * @param l the list to search (must be sorted) 676: * @param key the value to search for 677: * @param c the comparator by which the list is sorted 678: * @return the index at which the key was found, or -n-1 if it was not 679: * found, where n is the index of the first value higher than key or 680: * a.length if there is no such value 681: * @throws ClassCastException if key could not be compared with one of the 682: * elements of l 683: * @throws NullPointerException if a null element is compared with natural 684: * ordering (only possible when c is null) 685: * @see #sort(List, Comparator) 686: */ 687: public static <T> int binarySearch(List<? extends T> l, T key, 688: Comparator<? super T> c) 689: { 690: int pos = 0; 691: int low = 0; 692: int hi = l.size() - 1; 693: 694: // We use a linear search with log(n) comparisons using an iterator 695: // if the list is sequential-access. 696: if (isSequential(l)) 697: { 698: ListIterator<T> itr = ((List<T>) l).listIterator(); 699: int i = 0; 700: T o = itr.next(); // Assumes list is not empty (see isSequential) 701: boolean forward = true; 702: while (low <= hi) 703: { 704: pos = (low + hi) >>> 1; 705: if (i < pos) 706: { 707: if (!forward) 708: itr.next(); // Changing direction first. 709: for ( ; i != pos; i++, o = itr.next()) 710: ; 711: forward = true; 712: } 713: else 714: { 715: if (forward) 716: itr.previous(); // Changing direction first. 717: for ( ; i != pos; i--, o = itr.previous()) 718: ; 719: forward = false; 720: } 721: final int d = compare(o, key, c); 722: if (d == 0) 723: return pos; 724: else if (d > 0) 725: hi = pos - 1; 726: else 727: // This gets the insertion point right on the last loop 728: low = ++pos; 729: } 730: } 731: else 732: { 733: while (low <= hi) 734: { 735: pos = (low + hi) >>> 1; 736: final int d = compare(((List<T>) l).get(pos), key, c); 737: if (d == 0) 738: return pos; 739: else if (d > 0) 740: hi = pos - 1; 741: else 742: // This gets the insertion point right on the last loop 743: low = ++pos; 744: } 745: } 746: 747: // If we failed to find it, we do the same whichever search we did. 748: return -pos - 1; 749: } 750: 751: /** 752: * Copy one list to another. If the destination list is longer than the 753: * source list, the remaining elements are unaffected. This method runs in 754: * linear time. 755: * 756: * @param dest the destination list 757: * @param source the source list 758: * @throws IndexOutOfBoundsException if the destination list is shorter 759: * than the source list (the destination will be unmodified) 760: * @throws UnsupportedOperationException if dest.listIterator() does not 761: * support the set operation 762: */ 763: public static <T> void copy(List<? super T> dest, List<? extends T> source) 764: { 765: int pos = source.size(); 766: if (dest.size() < pos) 767: throw new IndexOutOfBoundsException("Source does not fit in dest"); 768: 769: Iterator<? extends T> i1 = source.iterator(); 770: ListIterator<? super T> i2 = dest.listIterator(); 771: 772: while (--pos >= 0) 773: { 774: i2.next(); 775: i2.set(i1.next()); 776: } 777: } 778: 779: /** 780: * Returns an Enumeration over a collection. This allows interoperability 781: * with legacy APIs that require an Enumeration as input. 782: * 783: * @param c the Collection to iterate over 784: * @return an Enumeration backed by an Iterator over c 785: */ 786: public static <T> Enumeration<T> enumeration(Collection<T> c) 787: { 788: final Iterator<T> i = c.iterator(); 789: return new Enumeration<T>() 790: { 791: /** 792: * Returns <code>true</code> if there are more elements to 793: * be enumerated. 794: * 795: * @return The result of <code>hasNext()</code> 796: * called on the underlying iterator. 797: */ 798: public final boolean hasMoreElements() 799: { 800: return i.hasNext(); 801: } 802: 803: /** 804: * Returns the next element to be enumerated. 805: * 806: * @return The result of <code>next()</code> 807: * called on the underlying iterator. 808: */ 809: public final T nextElement() 810: { 811: return i.next(); 812: } 813: }; 814: } 815: 816: /** 817: * Replace every element of a list with a given value. This method runs in 818: * linear time. 819: * 820: * @param l the list to fill. 821: * @param val the object to vill the list with. 822: * @throws UnsupportedOperationException if l.listIterator() does not 823: * support the set operation. 824: */ 825: public static <T> void fill(List<? super T> l, T val) 826: { 827: ListIterator<? super T> itr = l.listIterator(); 828: for (int i = l.size() - 1; i >= 0; --i) 829: { 830: itr.next(); 831: itr.set(val); 832: } 833: } 834: 835: /** 836: * Returns the starting index where the specified sublist first occurs 837: * in a larger list, or -1 if there is no matching position. If 838: * <code>target.size() > source.size()</code>, this returns -1, 839: * otherwise this implementation uses brute force, checking for 840: * <code>source.sublist(i, i + target.size()).equals(target)</code> 841: * for all possible i. 842: * 843: * @param source the list to search 844: * @param target the sublist to search for 845: * @return the index where found, or -1 846: * @since 1.4 847: */ 848: public static int indexOfSubList(List<?> source, List<?> target) 849: { 850: int ssize = source.size(); 851: for (int i = 0, j = target.size(); j <= ssize; i++, j++) 852: if (source.subList(i, j).equals(target)) 853: return i; 854: return -1; 855: } 856: 857: /** 858: * Returns the starting index where the specified sublist last occurs 859: * in a larger list, or -1 if there is no matching position. If 860: * <code>target.size() > source.size()</code>, this returns -1, 861: * otherwise this implementation uses brute force, checking for 862: * <code>source.sublist(i, i + target.size()).equals(target)</code> 863: * for all possible i. 864: * 865: * @param source the list to search 866: * @param target the sublist to search for 867: * @return the index where found, or -1 868: * @since 1.4 869: */ 870: public static int lastIndexOfSubList(List<?> source, List<?> target) 871: { 872: int ssize = source.size(); 873: for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--) 874: if (source.subList(i, j).equals(target)) 875: return i; 876: return -1; 877: } 878: 879: /** 880: * Returns an ArrayList holding the elements visited by a given 881: * Enumeration. This method exists for interoperability between legacy 882: * APIs and the new Collection API. 883: * 884: * @param e the enumeration to put in a list 885: * @return a list containing the enumeration elements 886: * @see ArrayList 887: * @since 1.4 888: */ 889: public static <T> ArrayList<T> list(Enumeration<T> e) 890: { 891: ArrayList<T> l = new ArrayList<T>(); 892: while (e.hasMoreElements()) 893: l.add(e.nextElement()); 894: return l; 895: } 896: 897: /** 898: * Find the maximum element in a Collection, according to the natural 899: * ordering of the elements. This implementation iterates over the 900: * Collection, so it works in linear time. 901: * 902: * @param c the Collection to find the maximum element of 903: * @return the maximum element of c 904: * @exception NoSuchElementException if c is empty 905: * @exception ClassCastException if elements in c are not mutually comparable 906: * @exception NullPointerException if null.compareTo is called 907: */ 908: public static <T extends Object & Comparable<? super T>> 909: T max(Collection<? extends T> c) 910: { 911: return max(c, null); 912: } 913: 914: /** 915: * Find the maximum element in a Collection, according to a specified 916: * Comparator. This implementation iterates over the Collection, so it 917: * works in linear time. 918: * 919: * @param c the Collection to find the maximum element of 920: * @param order the Comparator to order the elements by, or null for natural 921: * ordering 922: * @return the maximum element of c 923: * @throws NoSuchElementException if c is empty 924: * @throws ClassCastException if elements in c are not mutually comparable 925: * @throws NullPointerException if null is compared by natural ordering 926: * (only possible when order is null) 927: */ 928: public static <T> T max(Collection<? extends T> c, 929: Comparator<? super T> order) 930: { 931: Iterator<? extends T> itr = c.iterator(); 932: T max = itr.next