📄 collections.java
字号:
* * @return a comparator that imposes reverse natural ordering * @see Comparable * @see Serializable */ public static Comparator reverseOrder() { return rcInstance; } /** * The object for {@link #reverseOrder()}. */ static private final ReverseComparator rcInstance = new ReverseComparator(); /** * The implementation of {@link #reverseOrder()}. This class name * is required for compatibility with Sun's JDK serializability. * * @author Eric Blake <ebb9@email.byu.edu> */ private static final class ReverseComparator implements Comparator, Serializable { /** * Compatible with JDK 1.4. */ static private final long serialVersionUID = 7207038068494060240L; /** * A private constructor adds overhead. */ ReverseComparator() { } /** * Compare two objects in reverse natural order. * * @param a the first object * @param b the second object * @return <, ==, or > 0 according to b.compareTo(a) */ public int compare(Object a, Object b) { return ((Comparable) b).compareTo(a); } } /** * Rotate the elements in a list by a specified distance. After calling this * method, the element now at index <code>i</code> was formerly at index * <code>(i - distance) mod list.size()</code>. The list size is unchanged. * <p> * * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After * either <code>Collections.rotate(l, 4)</code> or * <code>Collections.rotate(l, -1)</code>, the new contents are * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate * just a portion of the list. For example, to move element <code>a</code> * forward two positions in the original example, use * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will * result in <code>[t, n, k, a, s]</code>. * <p> * * If the list is small or implements {@link RandomAccess}, the * implementation exchanges the first element to its destination, then the * displaced element, and so on until a circuit has been completed. The * process is repeated if needed on the second element, and so forth, until * all elements have been swapped. For large non-random lists, the * implementation breaks the list into two sublists at index * <code>-distance mod size</code>, calls {@link #reverse(List)} on the * pieces, then reverses the overall list. * * @param list the list to rotate * @param distance the distance to rotate by; unrestricted in value * @throws UnsupportedOperationException if the list does not support set * @since 1.4 */ public static void rotate(List list, int distance) { int size = list.size(); distance %= size; if (distance == 0) return; if (distance < 0) distance += size; if (isSequential(list)) { reverse(list); reverse(list.subList(0, distance)); reverse(list.subList(distance, size)); } else { // Determine the least common multiple of distance and size, as there // are (distance / LCM) loops to cycle through. int a = size; int lcm = distance; int b = a % lcm; while (b != 0) { a = lcm; lcm = b; b = a % lcm; } // Now, make the swaps. We must take the remainder every time through // the inner loop so that we don't overflow i to negative values. while (--lcm >= 0) { Object o = list.get(lcm); for (int i = lcm + distance; i != lcm; i = (i + distance) % size) o = list.set(i, o); list.set(lcm, o); } } } /** * Shuffle a list according to a default source of randomness. The algorithm * used iterates backwards over the list, swapping each element with an * element randomly selected from the elements in positions less than or * equal to it (using r.nextInt(int)). * <p> * * This algorithm would result in a perfectly fair shuffle (that is, each * element would have an equal chance of ending up in any position) if r were * a perfect source of randomness. In practice the results are merely very * close to perfect. * <p> * * This method operates in linear time. To do this on large lists which do * not implement {@link RandomAccess}, a temporary array is used to acheive * this speed, since it would be quadratic access otherwise. * * @param l the list to shuffle * @throws UnsupportedOperationException if l.listIterator() does not * support the set operation */ public static void shuffle(List l) { if (defaultRandom == null) { synchronized (Collections.class) { if (defaultRandom == null) defaultRandom = new Random(); } } shuffle(l, defaultRandom); } /** * Cache a single Random object for use by shuffle(List). This improves * performance as well as ensuring that sequential calls to shuffle() will * not result in the same shuffle order occurring: the resolution of * System.currentTimeMillis() is not sufficient to guarantee a unique seed. */ private static Random defaultRandom = null; /** * Shuffle a list according to a given source of randomness. The algorithm * used iterates backwards over the list, swapping each element with an * element randomly selected from the elements in positions less than or * equal to it (using r.nextInt(int)). * <p> * * This algorithm would result in a perfectly fair shuffle (that is, each * element would have an equal chance of ending up in any position) if r were * a perfect source of randomness. In practise (eg if r = new Random()) the * results are merely very close to perfect. * <p> * * This method operates in linear time. To do this on large lists which do * not implement {@link RandomAccess}, a temporary array is used to acheive * this speed, since it would be quadratic access otherwise. * * @param l the list to shuffle * @param r the source of randomness to use for the shuffle * @throws UnsupportedOperationException if l.listIterator() does not * support the set operation */ public static void shuffle(List l, Random r) { int lsize = l.size(); ListIterator i = l.listIterator(lsize); boolean sequential = isSequential(l); Object[] a = null; // stores a copy of the list for the sequential case if (sequential) a = l.toArray(); for (int pos = lsize - 1; pos > 0; --pos) { // Obtain a random position to swap with. pos + 1 is used so that the // range of the random number includes the current position. int swap = r.nextInt(pos + 1); // Swap the desired element. Object o; if (sequential) { o = a[swap]; a[swap] = i.previous(); } else o = l.set(swap, i.previous()); i.set(o); } } /** * Obtain an immutable Set consisting of a single element. The return value * of this method is Serializable. * * @param o the single element * @return an immutable Set containing only o * @see Serializable */ public static Set singleton(Object o) { return new SingletonSet(o); } /** * The implementation of {@link #singleton(Object)}. This class name * is required for compatibility with Sun's JDK serializability. * * @author Eric Blake <ebb9@email.byu.edu> */ private static final class SingletonSet extends AbstractSet implements Serializable { /** * Compatible with JDK 1.4. */ private static final long serialVersionUID = 3193687207550431679L; /** * The single element; package visible for use in nested class. * @serial the singleton */ final Object element; /** * Construct a singleton. * @param o the element */ SingletonSet(Object o) { element = o; } /** * The size: always 1! */ public int size() { return 1; } /** * Returns an iterator over the lone element. */ public Iterator iterator() { return new Iterator() { private boolean hasNext = true; public boolean hasNext() { return hasNext; } public Object next() { if (hasNext) { hasNext = false; return element; } else throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } }; } // The remaining methods are optional, but provide a performance // advantage by not allocating unnecessary iterators in AbstractSet. /** * The set only contains one element. */ public boolean contains(Object o) { return equals(o, element); } /** * This is true if the other collection only contains the element. */ public boolean containsAll(Collection c) { Iterator i = c.iterator(); int pos = c.size(); while (--pos >= 0) if (! equals(i.next(), element)) return false; return true; } /** * The hash is just that of the element. */ public int hashCode() { return hashCode(element); } /** * Returning an array is simple. */ public Object[] toArray() { return new Object[] {element}; } /** * Obvious string. */ public String toString() { return "[" + element + "]"; } } // class SingletonSet /** * Obtain an immutable List consisting of a single element. The return value * of this method is Serializable, and implements RandomAccess. * * @param o the single element * @return an immutable List containing only o * @see Serializable * @see RandomAccess * @since 1.3 */ public static List singletonList(Object o) { return new SingletonList(o); } /** * The implementation of {@link #singletonList(Object)}. This class name * is required for compatibility with Sun's JDK serializability. * * @author Eric Blake <ebb9@email.byu.edu> */ private static final class SingletonList extends AbstractList implements Serializable, RandomAccess { /** * Compatible with JDK 1.4. */ private static final long serialVersionUID = 3093736618740652951L; /** * The single element. * @serial the singleton */ private final Object element; /** * Construct a singleton. * @param o the element */ SingletonList(Object o) { element = o; } /** * The size: always 1! */ public int size() { return 1; } /** * Only index 0 is valid. */ public Object get(int index) { if (index == 0) return element; throw new IndexOutOfBoundsException(); } // The remaining methods are optional, but provide a performance // advantage by not allocating unnecessary iterators in AbstractList. /** * The set only contains one element. */ public boolean contains(Object o) { return equals(o, element); } /** * This is true if the other collection only contains the element. */ public boolean containsAll(Collection c) { Iterator i = c.iterator(); int pos = c.size(); while (--pos >= 0) if (! equals(i.next(), element)) return false; return true; } /** * Speed up the hashcode computation. */ public int hashCode() { return 31 + hashCode(element); } /** * Either the list has it or not. */ public int indexOf(Object o) { return equals(o, element) ? 0 : -1; } /** * Either the list has it or not. */ public int lastIndexOf(Object o) { return equals(o, element) ? 0 : -1; } /** * Sublists are limited in scope. */ public List subList(int from, int to) { if (from == to && (to == 0 || to == 1)) return EMPTY_LIST; if (from == 0 && to == 1) return this; if (from > to) throw new IllegalArgumentException(); throw new IndexOutOfBoundsException(); } /** * Returning an array is simple. */ public Object[] toArray() { return new Object[] {element}; } /** * Obvious string. */ public String toString() { return "[" + element + "]"; } } // class SingletonList /** * Obtain an immutable Map consisting of a single key-value pair. * The return value of this method is Serializable. * * @param key the single key * @param value the single value * @return an immutable Map containing only the single key-value pair * @see Serializable * @since 1.3 */ public static Map singletonMap(Object key, Object value) { return new SingletonMap(key, value); } /** * The implementation of {@link #singletonMap(Object)}. This class name * is required for compatibility with Sun's JDK serializability. * * @author Eric Blake <ebb9@email.byu.edu> */ private static final class SingletonMap extends AbstractMap implements Serializable { /** * Compatible with JDK 1.4. */ private static final long serialVersionUID = -6979724477215052911L;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -