/* * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.util;import java.io.Serializable;import java.io.ObjectOutputStream;import java.io.IOException;import java.lang.reflect.Array; /** * 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 or class objects 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}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @author Josh Bloch * @author Neal Gafter * @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 * {@linkplain Comparable natural ordering} of its elements. * All elements in the list must implement the {@link Comparable} * interface. Furthermore, all elements in the list must be * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} * must not throw a {@code ClassCastException} for any elements * {@code e1} and {@code e2} 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>Implementation note: This implementation is a stable, adaptive, * iterative mergesort that requires far fewer than n lg(n) comparisons * when the input array is partially sorted, while offering the * performance of a traditional mergesort when the input array is * randomly ordered. If the input array is nearly sorted, the * implementation requires approximately n comparisons. Temporary * storage requirements vary from a small constant for nearly sorted * input arrays to n/2 object references for randomly ordered input * arrays. * * <p>The implementation takes equal advantage of ascending and * descending order in its input array, and can take advantage of * ascending and descending order in different parts of the same * input array. It is well-suited to merging two or more sorted arrays: * simply concatenate the arrays and sort the resulting array. * * <p>The implementation was adapted from Tim Peters's list sort for Python * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic * Sorting and Information Theoretic Complexity", in Proceedings of the * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, * January 1993. * * <p>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 {@code set} operation. * @throws IllegalArgumentException (optional) if the implementation * detects that the natural ordering of the list elements is * found to violate the {@link Comparable} contract */ public static <T extends Comparable<? super T>> void sort(List<T> list) { Object[] a = list.toArray(); Arrays.sort(a); ListIterator<T> i = list.listIterator(); for (int j=0; j<a.length; j++) { i.next(); i.set((T)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, * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} * for any elements {@code e1} and {@code e2} 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>Implementation note: This implementation is a stable, adaptive, * iterative mergesort that requires far fewer than n lg(n) comparisons * when the input array is partially sorted, while offering the * performance of a traditional mergesort when the input array is * randomly ordered. If the input array is nearly sorted, the * implementation requires approximately n comparisons. Temporary * storage requirements vary from a small constant for nearly sorted * input arrays to n/2 object references for randomly ordered input * arrays. * * <p>The implementation takes equal advantage of ascending and * descending order in its input array, and can take advantage of * ascending and descending order in different parts of the same * input array. It is well-suited to merging two or more sorted arrays: * simply concatenate the arrays and sort the resulting array. * * <p>The implementation was adapted from Tim Peters's list sort for Python * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic * Sorting and Information Theoretic Complexity", in Proceedings of the * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, * January 1993. * * <p>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 * {@code null} 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 {@code set} operation. * @throws IllegalArgumentException (optional) if the comparator is * found to violate the {@link Comparator} contract */ public static <T> void sort(List<T> list, Comparator<? super T> c) { Object[] a = list.toArray(); Arrays.sort(a, (Comparator)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 {@linkplain Comparable natural ordering} of its * elements (as by the {@link #sort(List)} method) 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} interface 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 the 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 is not mutually comparable * with the elements of the list. */ public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) { if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key); else return Collections.iteratorBinarySearch(list, key); } private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) { int low = 0; int high = list.size()-1; while (low <= high) { int mid = (low + high) >>> 1; Comparable<? super T> midVal = list.get(mid); int cmp = 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 <T> int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key) { int low = 0; int high = list.size()-1; ListIterator<? extends Comparable<? super T>> i = list.listIterator(); while (low <= high) { int mid = (low + high) >>> 1; Comparable<? super T> midVal = get(i, mid); int cmp = 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 <T> T get(ListIterator<? extends T> i, int index) { T 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 * {@link #sort(List, Comparator) sort(List, Comparator)} * method), 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} interface 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. * @param c the comparator by which the list is ordered. * A <tt>null</tt> value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. * @return the 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 is not mutually comparable with the * elements of the list using this comparator. */ public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) { if (c==null) return binarySearch((List) list, key); if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key, c); else return Collections.iteratorBinarySearch(list, key, c); } private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) { int low = 0; int high = l.size()-1; while (low <= high) { int mid = (low + high) >>> 1; T 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 <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) { int low = 0; int high = l.size()-1; ListIterator<? extends T> i = l.listIterator(); while (low <= high) { int mid = (low + high) >>> 1; T midVal = get(i, 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 interface SelfComparable extends Comparable<SelfComparable> {} /** * Reverses the order of the elements in the specified list.<p> * * This method runs in linear time. * * @param list the list whose elements are to be reversed. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the <tt>set</tt> operation. */ public static void reverse(List<?> list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--) swap(list, i, j); } else { ListIterator fwd = list.listIterator(); ListIterator rev = list.listIterator(size); for (int i=0, mid=list.size()>>1; i<mid; i++) { Object tmp = fwd.next(); fwd.set(rev.previous()); rev.set(tmp); } } } /** * Randomly permutes the specified list using a default source of * randomness. All permutations occur with approximately equal * likelihood.<p> * * The hedge "approximately" is used in the foregoing description because * default source of randomness is only approximately an unbiased source * of independently chosen bits. If it were a perfect source of randomly * chosen bits, then the algorithm would choose permutations with perfect * uniformity.<p> * * This implementation traverses the list backwards, from the last element * up to the second, repeatedly swapping a randomly selected element into * the "current position". Elements are randomly selected from the * portion of the list that runs from the first element to the current * position, inclusive.<p> * * This method runs in linear time. If the specified list does not * implement the {@link RandomAccess} interface and is large, this * implementation dumps the specified list into an array before shuffling * it, and dumps the shuffled array back into the list. This avoids the * quadratic behavior that would result from shuffling a "sequential * access" list in place. * * @param list the list to be shuffled. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the <tt>set</tt> operation. */ public static void shuffle(List<?> list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); shuffle(list, rnd); } private static Random r; /** * Randomly permute the specified list using the specified source of * randomness. All permutations occur with equal likelihood * assuming that the source of randomness is fair.<p> * * This implementation traverses the list backwards, from the last element * up to the second, repeatedly swapping a randomly selected element into * the "current position". Elements are randomly selected from the * portion of the list that runs from the first element to the current * position, inclusive.<p> * * This method runs in linear time. If the specified list does not * implement the {@link RandomAccess} interface and is large, this * implementation dumps the specified list into an array before shuffling * it, and dumps the shuffled array back into the list. This avoids the * quadratic behavior that would result from shuffling a "sequential * access" list in place. * * @param list the list to be shuffled. * @param rnd the source of randomness to use to shuffle the list. * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the <tt>set</tt> operation. */ public static void shuffle(List<?> list, Random rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) swap(list, i-1, rnd.nextInt(i));Lines 1–500 of 3966. Load more
/* * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.util; import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.IOException; import java.lang.reflect.Array; /** * 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 or class objects 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}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @author Josh Bloch * @author Neal Gafter * @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 * {@linkplain Comparable natural ordering} of its elements. * All elements in the list must implement the {@link Comparable} * interface. Furthermore, all elements in the list must be * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} * must not throw a {@code ClassCastException} for any elements * {@code e1} and {@code e2} 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>Implementation note: This implementation is a stable, adaptive, * iterative mergesort that requires far fewer than n lg(n) comparisons * when the input array is partially sorted, while offering the * performance of a traditional mergesort when the input array is * randomly ordered. If the input array is nearly sorted, the * implementation requires approximately n comparisons. Temporary * storage requirements vary from a small constant for nearly sorted * input arrays to n/2 object references for randomly ordered input * arrays. * * <p>The implementation takes equal advantage of ascending and * descending order in its input array, and can take advantage of * ascending and descending order in different parts of the same * input array. It is well-suited to merging two or more sorted arrays: * simply concatenate the arrays and sort the resulting array. * * <p>The implementation was adapted from Tim Peters's list sort for Python * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic * Sorting and Information Theoretic Complexity", in Proceedings of the * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, * January 1993. * * <p>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 {@code set} operation. * @throws IllegalArgumentException (optional) if the implementation * detects that the natural ordering of the list elements is * found to violate the {@link Comparable} contract */ public static <T extends Comparable<? super T>> void sort(List<T> list) { Object[] a = list.toArray(); Arrays.sort(a); ListIterator<T> i = list.listIterator(); for (int j=0; j<a.length; j++) { i.next(); i.set((T)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, * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} * for any elements {@code e1} and {@code e2} 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>Implementation note: This implementation is a stable, adaptive, * iterative mergesort that requires far fewer than n lg(n) comparisons * when the input array is partially sorted, while offering the * performance of a traditional mergesort when the input array is * randomly ordered. If the input array is nearly sorted, the * implementation requires approximately n comparisons. Temporary * storage requirements vary from a small constant for nearly sorted * input arrays to n/2 object references for randomly ordered input * arrays. * * <p>The implementation takes equal advantage of ascending and * descending order in its input array, and can take advantage of * ascending and descending order in different parts of the same * input array. It is well-suited to merging two or more sorted arrays: * simply concatenate the arrays and sort the resulting array. * * <p>The implementation was adapted from Tim Peters's list sort for Python * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic * Sorting and Information Theoretic Complexity", in Proceedings of the * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, * January 1993. * * <p>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 * {@code null} 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 {@code set} operation. * @throws IllegalArgumentException (optional) if the comparator is * found to violate the {@link Comparator} contract */ public static <T> void sort(List<T> list, Comparator<? super T> c) { Object[] a = list.toArray(); Arrays.sort(a, (Comparator)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 {@linkplain Comparable natural ordering} of its * elements (as by the {@link #sort(List)} method) 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} interface 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 the 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 is not mutually comparable * with the elements of the list. */ public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) { if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key); else return Collections.iteratorBinarySearch(list, key); } private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) { int low = 0; int high = list.size()-1; while (low <= high) { int mid = (low + high) >>> 1; Comparable<? super T> midVal = list.get(mid); int cmp = 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 <T> int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key) { int low = 0; int high = list.size()-1; ListIterator<? extends Comparable<? super T>> i = list.listIterator(); while (low <= high) { int mid = (low + high) >>> 1; Comparable<? super T> midVal = get(i, mid); int cmp = 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 <T> T get(ListIterator<? extends T> i, int index) { T 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 * {@link #sort(List, Comparator) sort(List, Comparator)} * method), 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} interface 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. * @param c the comparator by which the list is ordered. * A <tt>null</tt> value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. * @return the 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 is not mutually comparable with the * elements of the list using this comparator. */ public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) { if (c==null) return binarySearch((List) list, key); if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key, c); else return Collections.iteratorBinarySearch(list, key, c); } private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) { int low = 0; int high = l.size()-1; while (low <= high) { int mid = (low + high) >>> 1; T 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 <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) { int low = 0; int high = l.size()-1; ListIterator<? extends T> i = l.listIterator(); while (low <= high) { int mid = (low + high) >>> 1; T midVal = get(i, 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 interface SelfComparable extends Comparable<SelfComparable> {} /** * Reverses the order of the elements in the specified list.<p> * * This method runs in linear time. * * @param list the list whose elements are to be reversed. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the <tt>set</tt> operation. */ public static void reverse(List<?> list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--) swap(list, i, j); } else { ListIterator fwd = list.listIterator(); ListIterator rev = list.listIterator(size); for (int i=0, mid=list.size()>>1; i<mid; i++) { Object tmp = fwd.next(); fwd.set(rev.previous()); rev.set(tmp); } } } /** * Randomly permutes the specified list using a default source of * randomness. All permutations occur with approximately equal * likelihood.<p> * * The hedge "approximately" is used in the foregoing description because * default source of randomness is only approximately an unbiased source * of independently chosen bits. If it were a perfect source of randomly * chosen bits, then the algorithm would choose permutations with perfect * uniformity.<p> * * This implementation traverses the list backwards, from the last element * up to the second, repeatedly swapping a randomly selected element into * the "current position". Elements are randomly selected from the * portion of the list that runs from the first element to the current * position, inclusive.<p> * * This method runs in linear time. If the specified list does not * implement the {@link RandomAccess} interface and is large, this * implementation dumps the specified list into an array before shuffling * it, and dumps the shuffled array back into the list. This avoids the * quadratic behavior that would result from shuffling a "sequential * access" list in place. * * @param list the list to be shuffled. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the <tt>set</tt> operation. */ public static void shuffle(List<?> list) { Random rnd = r; if (rnd == null) r = rnd = new Random(); shuffle(list, rnd); } private static Random r; /** * Randomly permute the specified list using the specified source of * randomness. All permutations occur with equal likelihood * assuming that the source of randomness is fair.<p> * * This implementation traverses the list backwards, from the last element * up to the second, repeatedly swapping a randomly selected element into * the "current position". Elements are randomly selected from the * portion of the list that runs from the first element to the current * position, inclusive.<p> * * This method runs in linear time. If the specified list does not * implement the {@link RandomAccess} interface and is large, this * implementation dumps the specified list into an array before shuffling * it, and dumps the shuffled array back into the list. This avoids the * quadratic behavior that would result from shuffling a "sequential * access" list in place. * * @param list the list to be shuffled. * @param rnd the source of randomness to use to shuffle the list. * @throws UnsupportedOperationException if the specified list or its * list-iterator does not support the <tt>set</tt> operation. */ public static void shuffle(List<?> list, Random rnd) { int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i=size; i>1; i--) swap(list, i-1, rnd.nextInt(i));