📄 collections.java
字号:
* @param coll the collection whose maximum element is to be determined. * @param comp the comparator with which to determine the maximum element. * A <tt>null</tt> value indicates that the elements' <i>natural * ordering</i> should be used. * @return the maximum element of the given collection, according * to the specified comparator. * @throws ClassCastException if the collection contains elements that are * not <i>mutually comparable</i> using the specified comparator. * @throws NoSuchElementException if the collection is empty. * @see Comparable */ public static Object max(Collection coll, Comparator comp) { if (comp==null) return max(coll); Iterator i = coll.iterator(); Object candidate = i.next(); while(i.hasNext()) { Object next = i.next(); if (comp.compare(next, candidate) > 0) candidate = next; } return candidate; } /** * Rotates the elements in the specified list by the specified distance. * After calling this method, the element at index <tt>i</tt> will be * the element previously at index <tt>(i - distance)</tt> mod * <tt>list.size()</tt>, for all values of <tt>i</tt> between <tt>0</tt> * and <tt>list.size()-1</tt>, inclusive. (This method has no effect on * the size of the list.) * * <p>For example, suppose <tt>list</tt> comprises<tt> [t, a, n, k, s]</tt>. * After invoking <tt>Collections.rotate(list, 1)</tt> (or * <tt>Collections.rotate(list, -4)</tt>), <tt>list</tt> will comprise * <tt>[s, t, a, n, k]</tt>. * * <p>Note that this method can usefully be applied to sublists to * move one or more elements within a list while preserving the * order of the remaining elements. For example, the following idiom * moves the element at index <tt>j</tt> forward to position * <tt>k</tt> (which must be greater than or equal to <tt>j</tt>): * <pre> * Collections.rotate(list.subList(j, k+1), -1); * </pre> * To make this concrete, suppose <tt>list</tt> comprises * <tt>[a, b, c, d, e]</tt>. To move the element at index <tt>1</tt> * (<tt>b</tt>) forward two positions, perform the following invocation: * <pre> * Collections.rotate(l.subList(1, 4), -1); * </pre> * The resulting list is <tt>[a, c, d, b, e]</tt>. * * <p>To move more than one element forward, increase the absolute value * of the rotation distance. To move elements backward, use a positive * shift distance. * * <p>If the specified list is small or implements the {@link * RandomAccess} interface, this implementation exchanges the first * element into the location it should go, and then repeatedly exchanges * the displaced element into the location it should go until a displaced * element is swapped into the first element. If necessary, the process * is repeated on the second and successive elements, until the rotation * is complete. If the specified list is large and doesn't implement the * <tt>RandomAccess</tt> interface, this implementation breaks the * list into two sublist views around index <tt>-distance mod size</tt>. * Then the {@link #reverse(List)} method is invoked on each sublist view, * and finally it is invoked on the entire list. For a more complete * description of both algorithms, see Section 2.3 of Jon Bentley's * <i>Programming Pearls</i> (Addison-Wesley, 1986). * * @param list the list to be rotated. * @param distance the distance to rotate the list. There are no * constraints on this value; it may be zero, negative, or * greater than <tt>list.size()</tt>. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the <tt>set</tt> method. * @since 1.4 */ public static void rotate(List list, int distance) { if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) rotate1(list, distance); else rotate2(list, distance); } private static void rotate1(List list, int distance) { int size = list.size(); if (size == 0) return; distance = distance % size; if (distance < 0) distance += size; if (distance == 0) return; for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) { Object displaced = list.get(cycleStart); int i = cycleStart; do { i += distance; if (i >= size) i -= size; displaced = list.set(i, displaced); nMoved ++; } while(i != cycleStart); } } private static void rotate2(List list, int distance) { int size = list.size(); if (size == 0) return; int mid = -distance % size; if (mid < 0) mid += size; if (mid == 0) return; Collections.reverse(list.subList(0, mid)); Collections.reverse(list.subList(mid, size)); Collections.reverse(list); } /** * Replaces all occurrences of one specified value in a list with another. * More formally, replaces with <tt>newVal</tt> each element <tt>e</tt> * in <tt>list</tt> such that * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>. * (This method has no effect on the size of the list.) * * @param list the list in which replacement is to occur. * @param oldVal the old value to be replaced. * @param newVal the new value with which <tt>oldVal</tt> is to be * replaced. * @return <tt>true</tt> if <tt>list</tt> contained one or more elements * <tt>e</tt> such that * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the <tt>set</tt> method. * @since 1.4 */ public static boolean replaceAll(List list, Object oldVal, Object newVal) { boolean result = false; int size = list.size(); if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { if (oldVal==null) { for (int i=0; i<size; i++) { if (list.get(i)==null) { list.set(i, newVal); result = true; } } } else { for (int i=0; i<size; i++) { if (oldVal.equals(list.get(i))) { list.set(i, newVal); result = true; } } } } else { ListIterator itr=list.listIterator(); if (oldVal==null) { for (int i=0; i<size; i++) { if (itr.next()==null) { itr.set(newVal); result = true; } } } else { for (int i=0; i<size; i++) { if (oldVal.equals(itr.next())) { itr.set(newVal); result = true; } } } } return result; } /** * Returns the starting position of the first occurrence of the specified * target list within the specified source list, or -1 if there is no * such occurrence. More formally, returns the the lowest index <tt>i</tt> * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>, * or -1 if there is no such index. (Returns -1 if * <tt>target.size() > source.size()</tt>.) * * <p>This implementation uses the "brute force" technique of scanning * over the source list, looking for a match with the target at each * location in turn. * * @param source the list in which to search for the first occurrence * of <tt>target</tt>. * @param target the list to search for as a subList of <tt>source</tt>. * @return the starting position of the first occurrence of the specified * target list within the specified source list, or -1 if there * is no such occurrence. * @since 1.4 */ public static int indexOfSubList(List source, List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; if (sourceSize < INDEXOFSUBLIST_THRESHOLD || (source instanceof RandomAccess&&target instanceof RandomAccess)) { nextCand: for (int candidate = 0; candidate <= maxCandidate; candidate++) { for (int i=0, j=candidate; i<targetSize; i++, j++) if (!eq(target.get(i), source.get(j))) continue nextCand; // Element mismatch, try next cand return candidate; // All elements of candidate matched target } } else { // Iterator version of above algorithm ListIterator si = source.listIterator(); nextCand: for (int candidate = 0; candidate <= maxCandidate; candidate++) { ListIterator ti = target.listIterator(); for (int i=0; i<targetSize; i++) { if (!eq(ti.next(), si.next())) { // Back up source iterator to next candidate for (int j=0; j<i; j++) si.previous(); continue nextCand; } } return candidate; } } return -1; // No candidate matched the target } /** * Returns the starting position of the last occurrence of the specified * target list within the specified source list, or -1 if there is no such * occurrence. More formally, returns the the highest index <tt>i</tt> * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>, * or -1 if there is no such index. (Returns -1 if * <tt>target.size() > source.size()</tt>.) * * <p>This implementation uses the "brute force" technique of iterating * over the source list, looking for a match with the target at each * location in turn. * * @param source the list in which to search for the last occurrence * of <tt>target</tt>. * @param target the list to search for as a subList of <tt>source</tt>. * @return the starting position of the last occurrence of the specified * target list within the specified source list, or -1 if there * is no such occurrence. * @since 1.4 */ public static int lastIndexOfSubList(List source, List target) { int sourceSize = source.size(); int targetSize = target.size(); int maxCandidate = sourceSize - targetSize; if (sourceSize < INDEXOFSUBLIST_THRESHOLD || source instanceof RandomAccess) { // Index access version nextCand: for (int candidate = maxCandidate; candidate >= 0; candidate--) { for (int i=0, j=candidate; i<targetSize; i++, j++) if (!eq(target.get(i), source.get(j))) continue nextCand; // Element mismatch, try next cand return candidate; // All elements of candidate matched target } } else { // Iterator version of above algorithm if (maxCandidate < 0) return -1; ListIterator si = source.listIterator(maxCandidate); nextCand: for (int candidate = maxCandidate; candidate >= 0; candidate--) { ListIterator ti = target.listIterator(); for (int i=0; i<targetSize; i++) { if (!eq(ti.next(), si.next())) { if (candidate != 0) { // Back up source iterator to next candidate for (int j=0; j<=i+1; j++) si.previous(); } continue nextCand; } } return candidate; } } return -1; // No candidate matched the target } // Unmodifiable Wrappers /** * Returns an unmodifiable view of the specified collection. This method * allows modules to provide users with "read-only" access to internal * collections. Query operations on the returned collection "read through" * to the specified collection, and attempts to modify the returned * collection, whether direct or via its iterator, result in an * <tt>UnsupportedOperationException</tt>.<p> * * The returned collection does <i>not</i> pass the hashCode and equals * operations through to the backing collection, but relies on * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods. This * is necessary to preserve the contracts of these operations in the case * that the backing collection is a set or a list.<p> * * The returned collection will be serializable if the specified collection * is serializable. * * @param c the collection for which an unmodifiable view is to be * returned. * @return an unmodifiable view of the specified collection. */ public static Collection unmodifiableCollection(Collection c) { return new UnmodifiableCollection(c); } /** * @serial include */ static class UnmodifiableCollection implements Collection, Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = 1820017752578914078L; Collection c; UnmodifiableCollection(Collection c) { if (c==null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -