📄 collections.java
字号:
/* * @(#)Collections.java 1.66 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.util;import java.io.Serializable;/** * This class consists exclusively of static methods that operate on or return * collections. It contains polymorphic algorithms that operate on * collections, "wrappers", which return a new collection backed by a * specified collection, and a few other odds and ends. * * <p>The methods of this class all throw a <tt>NullPointerException</tt> * if the collections provided to them are null. * * <p>The documentation for the polymorphic algorithms contained in this class * generally includes a brief description of the <i>implementation</i>. Such * descriptions should be regarded as <i>implementation notes</i>, rather than * parts of the <i>specification</i>. Implementors should feel free to * substitute other algorithms, so long as the specification itself is adhered * to. (For example, the algorithm used by <tt>sort</tt> does not have to be * a mergesort, but it does have to be <i>stable</i>.) * * <p>The "destructive" algorithms contained in this class, that is, the * algorithms that modify the collection on which they operate, are specified * to throw <tt>UnsupportedOperationException</tt> if the collection does not * support the appropriate mutation primitive(s), such as the <tt>set</tt> * method. These algorithms may, but are not required to, throw this * exception if an invocation would have no effect on the collection. For * example, invoking the <tt>sort</tt> method on an unmodifiable list that is * already sorted may or may not throw <tt>UnsupportedOperationException</tt>. * * <p>This class is a member of the * <a href="{@docRoot}/../guide/collections/index.html"> * Java Collections Framework</a>. * * @author Josh Bloch * @version 1.66, 01/23/03 * @see Collection * @see Set * @see List * @see Map * @since 1.2 */public class Collections { // Suppresses default constructor, ensuring non-instantiability. private Collections() { } // Algorithms /* * Tuning parameters for algorithms - Many of the List algorithms have * two implementations, one of which is appropriate for RandomAccess * lists, the other for "sequential." Often, the random access variant * yields better performance on small sequential access lists. The * tuning parameters below determine the cutoff point for what constitutes * a "small" sequential access list for each algorithm. The values below * were empirically determined to work well for LinkedList. Hopefully * they should be reasonable for other sequential access List * implementations. Those doing performance work on this code would * do well to validate the values of these parameters from time to time. * (The first word of each tuning parameter name is the algorithm to which * it applies.) */ private static final int BINARYSEARCH_THRESHOLD = 5000; private static final int REVERSE_THRESHOLD = 18; private static final int SHUFFLE_THRESHOLD = 5; private static final int FILL_THRESHOLD = 25; private static final int ROTATE_THRESHOLD = 100; private static final int COPY_THRESHOLD = 10; private static final int REPLACEALL_THRESHOLD = 11; private static final int INDEXOFSUBLIST_THRESHOLD = 35; /** * Sorts the specified list into ascending order, according to the * <i>natural ordering</i> of its elements. All elements in the list must * implement the <tt>Comparable</tt> interface. Furthermore, all elements * in the list must be <i>mutually comparable</i> (that is, * <tt>e1.compareTo(e2)</tt> must not throw a <tt>ClassCastException</tt> * for any elements <tt>e1</tt> and <tt>e2</tt> in the list).<p> * * This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort.<p> * * The specified list must be modifiable, but need not be resizable.<p> * * The sorting algorithm is a modified mergesort (in which the merge is * omitted if the highest element in the low sublist is less than the * lowest element in the high sublist). This algorithm offers guaranteed * n log(n) performance. * * This implementation dumps the specified list into an array, sorts * the array, and iterates over the list resetting each element * from the corresponding position in the array. This avoids the * n<sup>2</sup> log(n) performance that would result from attempting * to sort a linked list in place. * * @param list the list to be sorted. * @throws ClassCastException if the list contains elements that are not * <i>mutually comparable</i> (for example, strings and integers). * @throws UnsupportedOperationException if the specified list's * list-iterator does not support the <tt>set</tt> operation. * @see Comparable */ public static void sort(List list) { Object a[] = list.toArray(); Arrays.sort(a); ListIterator i = list.listIterator(); for (int j=0; j<a.length; j++) { i.next(); i.set(a[j]); } } /** * Sorts the specified list according to the order induced by the * specified comparator. All elements in the list must be <i>mutually * comparable</i> using the specified comparator (that is, * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt> * for any elements <tt>e1</tt> and <tt>e2</tt> in the list).<p> * * This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort.<p> * * The sorting algorithm is a modified mergesort (in which the merge is * omitted if the highest element in the low sublist is less than the * lowest element in the high sublist). This algorithm offers guaranteed * n log(n) performance. * * The specified list must be modifiable, but need not be resizable. * This implementation dumps the specified list into an array, sorts * the array, and iterates over the list resetting each element * from the corresponding position in the array. This avoids the * n<sup>2</sup> log(n) performance that would result from attempting * to sort a linked list in place. * * @param list the list to be sorted. * @param c the comparator to determine the order of the list. A * <tt>null</tt> value indicates that the elements' <i>natural * ordering</i> should be used. * @throws ClassCastException if the list contains elements that are not * <i>mutually comparable</i> using the specified comparator. * @throws UnsupportedOperationException if the specified list's * list-iterator does not support the <tt>set</tt> operation. * @see Comparator */ public static void sort(List list, Comparator c) { Object a[] = list.toArray(); Arrays.sort(a, c); ListIterator i = list.listIterator(); for (int j=0; j<a.length; j++) { i.next(); i.set(a[j]); } } /** * Searches the specified list for the specified object using the binary * search algorithm. The list must be sorted into ascending order * according to the <i>natural ordering</i> of its elements (as by the * <tt>sort(List)</tt> method, above) prior to making this call. If it is * not sorted, the results are undefined. If the list contains multiple * elements equal to the specified object, there is no guarantee which one * will be found.<p> * * This method runs in log(n) time for a "random access" list (which * provides near-constant-time positional access). If the specified list * does not implement the {@link RandomAccess} and is large, this method * will do an iterator-based binary search that performs O(n) link * traversals and O(log n) element comparisons. * * @param list the list to be searched. * @param key the key to be searched for. * @return index of the search key, if it is contained in the list; * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The * <i>insertion point</i> is defined as the point at which the * key would be inserted into the list: the index of the first * element greater than the key, or <tt>list.size()</tt>, if all * elements in the list are less than the specified key. Note * that this guarantees that the return value will be >= 0 if * and only if the key is found. * @throws ClassCastException if the list contains elements that are not * <i>mutually comparable</i> (for example, strings and * integers), or the search key in not mutually comparable * with the elements of the list. * @see Comparable * @see #sort(List) */ public static int binarySearch(List list, Object key) { if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return indexedBinarySearch(list, key); else return iteratorBinarySearch(list, key); } private static int indexedBinarySearch(List list, Object key) { int low = 0; int high = list.size()-1; while (low <= high) { int mid = (low + high) >> 1; Object midVal = list.get(mid); int cmp = ((Comparable)midVal).compareTo(key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found } private static int iteratorBinarySearch(List list, Object key) { int low = 0; int high = list.size()-1; ListIterator i = list.listIterator(); while (low <= high) { int mid = (low + high) >> 1; Object midVal = get(i, mid); int cmp = ((Comparable)midVal).compareTo(key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found } /** * Gets the ith element from the given list by repositioning the specified * list listIterator. */ private static Object get(ListIterator i, int index) { Object obj = null; int pos = i.nextIndex(); if (pos <= index) { do { obj = i.next(); } while (pos++ < index); } else { do { obj = i.previous(); } while (--pos > index); } return obj; } /** * Searches the specified list for the specified object using the binary * search algorithm. The list must be sorted into ascending order * according to the specified comparator (as by the <tt>Sort(List, * Comparator)</tt> method, above), prior to making this call. If it is * not sorted, the results are undefined. If the list contains multiple * elements equal to the specified object, there is no guarantee which one * will be found.<p> * * This method runs in log(n) time for a "random access" list (which * provides near-constant-time positional access). If the specified list * does not implement the {@link RandomAccess} and is large, this * this method will do an iterator-based binary search that performs * O(n) link traversals and O(log n) element comparisons. * * @param list the list to be searched. * @param key the key to be searched for. * @param c the comparator by which the list is ordered. A * <tt>null</tt> value indicates that the elements' <i>natural * ordering</i> should be used. * @return index of the search key, if it is contained in the list; * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The * <i>insertion point</i> is defined as the point at which the * key would be inserted into the list: the index of the first * element greater than the key, or <tt>list.size()</tt>, if all * elements in the list are less than the specified key. Note * that this guarantees that the return value will be >= 0 if * and only if the key is found. * @throws ClassCastException if the list contains elements that are not * <i>mutually comparable</i> using the specified comparator, * or the search key in not mutually comparable with the * elements of the list using this comparator. * @see Comparable * @see #sort(List, Comparator) */ public static int binarySearch(List list, Object key, Comparator c) { if (c==null) return binarySearch(list, key); if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return indexedBinarySearch(list, key, c); else return iteratorBinarySearch(list, key, c); } private static int indexedBinarySearch(List l, Object key, Comparator c) { int low = 0; int high = l.size()-1; while (low <= high) { int mid = (low + high) >> 1; Object midVal = l.get(mid); int cmp = c.compare(midVal, key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found } private static int iteratorBinarySearch(List l, Object key, Comparator c) { int low = 0; int high = l.size()-1; ListIterator i = l.listIterator(); while (low <= high) { int mid = (low + high) >> 1; Object midVal = get(i, mid); int cmp = c.compare(midVal, key); if (cmp < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -