JDK1.8源码Collections
正文:
一、概述:
此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。
如果为此类的方法所提供的 collection 或类对象为 null,则这些方法都将抛出 NullPointerException。
此类中所含多态算法的文档通常包括对实现 的简短描述。应该将这类描述视为实现注意事项,而不是规范 的一部分。实现者应该可以随意使用其他算法替代,只要遵循规范本身即可。(例如,sort 使用的算法不一定是合并排序算法,但它必须是稳定的。)
此类中包含的“破坏性”算法,即可修改其所操作的 collection 的算法,该算法被指定在 collection 不支持适当的可变基元(比如 set 方法)时抛出 UnsupportedOperationException。如果调用不会对 collection 产生任何影响,那么这些算法可能(但不要求)抛出此异常。例如,在已经排序的、不可修改列表上调用 sort 方法可能会(也可能不会)抛出 UnsupportedOperationException。
二、拓展点
1,<T> Comparator<T> reverseOrder()分析
源码解释:
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
(自然顺序是通过对象自身的 compareTo 方法强行排序的。)
此方法允许使用单个语句,以逆自然顺序对实现了 Comparable 接口的对象 collection(或数组)进行排序(或维护)。
例如,假设 a 是一个字符串数组。那么: Arrays.sort(a, Collections.reverseOrder());
将按照逆字典(字母)顺序对数组进行排序。
/**
* Returns a comparator that imposes the reverse of the <em>natural
* ordering</em> on a collection of objects that implement the
* {@code Comparable} interface. (The natural ordering is the ordering
* imposed by the objects' own {@code compareTo} method.) This enables a
* simple idiom for sorting (or maintaining) collections (or arrays) of
* objects that implement the {@code Comparable} interface in
* reverse-natural-order. For example, suppose {@code a} is an array of
* strings. Then: <pre>
* Arrays.sort(a, Collections.reverseOrder());
* </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
*
* The returned comparator is serializable.
*
* @param <T> the class of the objects compared by the comparator
* @return A comparator that imposes the reverse of the <i>natural
* ordering</i> on a collection of objects that implement
* the <tt>Comparable</tt> interface.
* @see Comparable
*/
@SuppressWarnings("unchecked")
public static <T> Comparator<T> reverseOrder() {
return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
} /**
* @serial include
*/
private static class ReverseComparator
implements Comparator<Comparable<Object>>, Serializable { private static final long serialVersionUID = 7207038068494060240L; static final ReverseComparator REVERSE_ORDER
= new ReverseComparator(); public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c2.compareTo(c1);
} private Object readResolve() { return Collections.reverseOrder(); } @Override
public Comparator<Comparable<Object>> reversed() {
return Comparator.naturalOrder();
}
}
示例:
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(5);
list.add(2);
list.add(3);
list.add(6);
list.add(4);
list.add(7);
System.out.println("原顺序:"+list);
Collections.sort(list);
Comparator<Object> objectComparator = Collections.reverseOrder();
Collections.sort(list,objectComparator);
System.out.println("逆转后顺序:"+list);
}
结果:
原顺序:[1, 5, 2, 3, 6, 4, 7]
逆转后顺序:[7, 6, 5, 4, 3, 2, 1]
在调用Collections.reverseOrder() 方法时调用了内部类的构造方法创建 ReverseComparator,
只有在调用 Collections.sort(list,objectComparator)时,逆转比较器作为参数,将调用内部的方法
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c2.compareTo(c1);
}
该方法才是顺序逆转的核心!
三、其他源码:
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.
*
* @implNote
* This implementation defers to the {@link List#sort(Comparator)}
* method using the specified list and a {@code null} comparator.
*
* @param <T> the class of the objects in the list
* @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
* @see List#sort(Comparator)
*/
//根据元素的自然顺序 对指定列表按升序进行排序。列表中的所有元素都必须实现 Comparable 接口
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
} /**
* 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.
*
* @implNote
* This implementation defers to the {@link List#sort(Comparator)}
* method using the specified list and comparator.
*
* @param <T> the class of the objects in the list
* @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
* @see List#sort(Comparator)
*/
//根据指定比较器产生的顺序对指定列表进行排序。
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
} /**
* 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 <T> the class of the objects in the list
* @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.
*/
//使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过 sort(List) //方法)。如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。
public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {
//ArrayList implement RandomAccess,而LinkedList没有实现 RandomAccess,list.size()>5000时使用普通二次搜索查找法消耗的性能过大
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 <T> the class of the objects in the list
* @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.
*/
//使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据指定的比较器对列表进行升序排序(通过 sort(List, Comparator) //方法)。如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。
@SuppressWarnings("unchecked")
public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
if (c==null)
return binarySearch((List<? extends Comparable<? super T>>) 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
} /**
* 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.
*/
//反转指定列表中元素的顺序。
@SuppressWarnings({"rawtypes", "unchecked"})
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 {
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator fwd = list.lis tIterator();
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.
*/
//使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
//此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。
//元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。
//此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到数组中,
//并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。
public static void shuffle(List<?> list) {
Random rnd = r;
if (rnd == null)
r = rnd = new Random(); // harmless race.
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.
*/
//使用指定的随机源对指定列表进行置换。所有置换发生的可能性都是相等的,假定随机源是公平的。
//同方法:shuffle(List<?> list)
@SuppressWarnings({"rawtypes", "unchecked"})
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));
} else {
Object arr[] = list.toArray(); // Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i)); // Dump array back into list
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
} /**
* Swaps the elements at the specified positions in the specified list.
* (If the specified positions are equal, invoking this method leaves
* the list unchanged.)
*
* @param list The list in which to swap elements.
* @param i the index of one element to be swapped.
* @param j the index of the other element to be swapped.
* @throws IndexOutOfBoundsException if either <tt>i</tt> or <tt>j</tt>
* is out of range (i < 0 || i >= list.size()
* || j < 0 || j >= list.size()).
* @since 1.4
*/
//在指定列表的指定位置处交换元素
@SuppressWarnings({"rawtypes", "unchecked"})
public static void swap(List<?> list, int i, int j) {
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
final List l = list;
l.set(i, l.set(j, l.get(i)));
} /**
* Swaps the two specified elements in the specified array.
*/
private static void swap(Object[] arr, int i, int j) {
Object tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
} /**
* Replaces all of the elements of the specified list with the specified
* element. <p>
*
* This method runs in linear time.
*
* @param <T> the class of the objects in the list
* @param list the list to be filled with the specified element.
* @param obj The element with which to fill the specified list.
* @throws UnsupportedOperationException if the specified list or its
* list-iterator does not support the <tt>set</tt> operation.
*/
//使用指定元素替换指定列表中的所有元素。
public static <T> void fill(List<? super T> list, T obj) {
int size = list.size(); if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
for (int i=0; i<size; i++)
list.set(i, obj);
} else {
ListIterator<? super T> itr = list.listIterator();
for (int i=0; i<size; i++) {
itr.next();
itr.set(obj);
}
}
} /**
* Copies all of the elements from one list into another. After the
* operation, the index of each copied element in the destination list
* will be identical to its index in the source list. The destination
* list must be at least as long as the source list. If it is longer, the
* remaining elements in the destination list are unaffected. <p>
*
* This method runs in linear time.
*
* @param <T> the class of the objects in the lists
* @param dest The destination list.
* @param src The source list.
* @throws IndexOutOfBoundsException if the destination list is too small
* to contain the entire source List.
* @throws UnsupportedOperationException if the destination list's
* list-iterator does not support the <tt>set</tt> operation.
*/
//将所有元素从一个列表复制到另一个列表
//目标列表的长度至少必须等于源列表。
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
int srcSize = src.size();
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest"); if (srcSize < COPY_THRESHOLD ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i<srcSize; i++)
dest.set(i, src.get(i));
} else {
ListIterator<? super T> di=dest.listIterator();
ListIterator<? extends T> si=src.listIterator();
for (int i=0; i<srcSize; i++) {
di.next();
di.set(si.next());
}
}
} /**
* Returns the minimum element of the given collection, according to the
* <i>natural ordering</i> of its elements. All elements in the
* collection must implement the <tt>Comparable</tt> interface.
* Furthermore, all elements in the collection 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 collection).<p>
*
* This method iterates over the entire collection, hence it requires
* time proportional to the size of the collection.
*
* @param <T> the class of the objects in the collection
* @param coll the collection whose minimum element is to be determined.
* @return the minimum element of the given collection, according
* to the <i>natural ordering</i> of its elements.
* @throws ClassCastException if the collection contains elements that are
* not <i>mutually comparable</i> (for example, strings and
* integers).
* @throws NoSuchElementException if the collection is empty.
* @see Comparable
*/
//根据元素的自然顺序 返回给定 collection 的最小元素。collection 中的所有元素都必须实现 Comparable 接口。
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next(); while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) < 0)
candidate = next;
}
return candidate;
} /**
* Returns the minimum element of the given collection, according to the
* order induced by the specified comparator. All elements in the
* collection must be <i>mutually comparable</i> by the specified
* comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
* <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
* <tt>e2</tt> in the collection).<p>
*
* This method iterates over the entire collection, hence it requires
* time proportional to the size of the collection.
*
* @param <T> the class of the objects in the collection
* @param coll the collection whose minimum element is to be determined.
* @param comp the comparator with which to determine the minimum element.
* A <tt>null</tt> value indicates that the elements' <i>natural
* ordering</i> should be used.
* @return the minimum 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
*/
//根据指定比较器产生的顺序,返回给定 collection 的最小元素。同min
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)min((Collection) coll); Iterator<? extends T> i = coll.iterator();
T candidate = i.next(); while (i.hasNext()) {
T next = i.next();
if (comp.compare(next, candidate) < 0)
candidate = next;
}
return candidate;
} /**
* Returns the maximum element of the given collection, according to the
* <i>natural ordering</i> of its elements. All elements in the
* collection must implement the <tt>Comparable</tt> interface.
* Furthermore, all elements in the collection 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 collection).<p>
*
* This method iterates over the entire collection, hence it requires
* time proportional to the size of the collection.
*
* @param <T> the class of the objects in the collection
* @param coll the collection whose maximum element is to be determined.
* @return the maximum element of the given collection, according
* to the <i>natural ordering</i> of its elements.
* @throws ClassCastException if the collection contains elements that are
* not <i>mutually comparable</i> (for example, strings and
* integers).
* @throws NoSuchElementException if the collection is empty.
* @see Comparable
*/
//根据元素的自然顺序,返回给定 collection 的最大元素。同min
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next(); while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) > 0)
candidate = next;
}
return candidate;
} /**
* Returns the maximum element of the given collection, according to the
* order induced by the specified comparator. All elements in the
* collection must be <i>mutually comparable</i> by the specified
* comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
* <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
* <tt>e2</tt> in the collection).<p>
*
* This method iterates over the entire collection, hence it requires
* time proportional to the size of the collection.
*
* @param <T> the class of the objects in the collection
* @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
*/
//根据指定比较器产生的顺序,返回给定 collection 的最大元素。同min
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)max((Collection) coll); Iterator<? extends T> i = coll.iterator();
T candidate = i.next(); while (i.hasNext()) {
T 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> operation.
* @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);
} 示例:会改变list的数据结构
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(0);
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list);
List<Integer> integers = list.subList(1, 4);
System.out.println(integers);
Collections.rotate(integers,1);
System.out.println(list);
} 结果:
[0, 1, 2, 3, 4, 5]
[1, 2, 3]
[0, 3, 1, 2, 4, 5] private static <T> void rotate1(List<T> 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++) {
T 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; reverse(list.subList(0, mid));
reverse(list.subList(mid, size));
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 <T> the class of the objects in 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> operation.
* @since 1.4
*/
//使用另一个值替换列表中出现的所有某一指定值。
//更确切地讲,使用 newVal 替换 list 中满足 (oldVal==null ? e==null : oldVal.equals(e)) 的每个 e 元素。
public static <T> boolean replaceAll(List<T> list, T oldVal, T 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<T> 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 lowest index <tt>i</tt>
* such that {@code source.subList(i, i+target.size()).equals(target)},
* or -1 if there is no such index. (Returns -1 if
* {@code target.size() > source.size()})
*
* <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
*/
//返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
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 highest index <tt>i</tt>
* such that {@code source.subList(i, i+target.size()).equals(target)},
* or -1 if there is no such index. (Returns -1 if
* {@code target.size() > source.size()})
*
* <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
*/
//返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
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 <T> the class of the objects in the collection
* @param c the collection for which an unmodifiable view is to be
* returned.
* @return an unmodifiable view of the specified collection.
*/
//返回指定 collection 的不可修改视图。此方法允许模块为用户提供对内部 collection 的“只读”访问。
//在返回的 collection 上执行的查询操作将“读完”指定的 collection。
//人为的给普通容器加上不可修改的特性
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
return new UnmodifiableCollection<>(c);
} /**
* @serial include
*/
static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 1820017752578914078L; final Collection<? extends E> c; UnmodifiableCollection(Collection<? extends E> c) {
if (c==null)
throw new NullPointerException();
this.c = c;
} public int size() {return c.size();}
public boolean isEmpty() {return c.isEmpty();}
public boolean contains(Object o) {return c.contains(o);}
public Object[] toArray() {return c.toArray();}
public <T> T[] toArray(T[] a) {return c.toArray(a);}
public String toString() {return c.toString();} public Iterator<E> iterator() {
return new Iterator<E>() {
private final Iterator<? extends E> i = c.iterator(); public boolean hasNext() {return i.hasNext();}
public E next() {return i.next();}
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
// Use backing collection version
i.forEachRemaining(action);
}
};
} public boolean add(E e) {
throw new UnsupportedOperationException();
}
public boolean remove(Object o) {
throw new UnsupportedOperationException();
} public boolean containsAll(Collection<?> coll) {
return c.containsAll(coll);
}
public boolean addAll(Collection<? extends E> coll) {
throw new UnsupportedOperationException();
}
public boolean removeAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public boolean retainAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
} // Override default methods in Collection
@Override
public void forEach(Consumer<? super E> action) {
c.forEach(action);
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
@Override
public Spliterator<E> spliterator() {
return (Spliterator<E>)c.spliterator();
}
@SuppressWarnings("unchecked")
@Override
public Stream<E> stream() {
return (Stream<E>)c.stream();
}
@SuppressWarnings("unchecked")
@Override
public Stream<E> parallelStream() {
return (Stream<E>)c.parallelStream();
}
} /**
* Returns an unmodifiable view of the specified set. This method allows
* modules to provide users with "read-only" access to internal sets.
* Query operations on the returned set "read through" to the specified
* set, and attempts to modify the returned set, whether direct or via its
* iterator, result in an <tt>UnsupportedOperationException</tt>.<p>
*
* The returned set will be serializable if the specified set
* is serializable.
*
* @param <T> the class of the objects in the set
* @param s the set for which an unmodifiable view is to be returned.
* @return an unmodifiable view of the specified set.
*/
//返回指定 set 的不可修改视图。此方法允许模块为用户提供对内部 set 的“只读”访问。
//在返回的 set 上执行的查询操作将“读完”指定的 set。
public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
return new UnmodifiableSet<>(s);
} /**
* @serial include
*/
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
implements Set<E>, Serializable {
private static final long serialVersionUID = -9215047833775013803L; UnmodifiableSet(Set<? extends E> s) {super(s);}
public boolean equals(Object o) {return o == this || c.equals(o);}
public int hashCode() {return c.hashCode();}
} /**
* Returns an unmodifiable view of the specified sorted set. This method
* allows modules to provide users with "read-only" access to internal
* sorted sets. Query operations on the returned sorted set "read
* through" to the specified sorted set. Attempts to modify the returned
* sorted set, whether direct, via its iterator, or via its
* <tt>subSet</tt>, <tt>headSet</tt>, or <tt>tailSet</tt> views, result in
* an <tt>UnsupportedOperationException</tt>.<p>
*
* The returned sorted set will be serializable if the specified sorted set
* is serializable.
*
* @param <T> the class of the objects in the set
* @param s the sorted set for which an unmodifiable view is to be
* returned.
* @return an unmodifiable view of the specified sorted set.
*/
//返回指定有序 set 的不可修改视图。此方法允许模块为用户提供对内部有序 set 的“只读”访问。
//在返回的有序 set 上执行的查询操作将“读完”指定的有序 set。
public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
return new UnmodifiableSortedSet<>(s);
} /**
* @serial include
*/
static class UnmodifiableSortedSet<E>
extends UnmodifiableSet<E>
implements SortedSet<E>, Serializable {
private static final long serialVersionUID = -4929149591599911165L;
private final SortedSet<E> ss; UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;} public Comparator<? super E> comparator() {return ss.comparator();} public SortedSet<E> subSet(E fromElement, E toElement) {
return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement));
}
public SortedSet<E> headSet(E toElement) {
return new UnmodifiableSortedSet<>(ss.headSet(toElement));
}
public SortedSet<E> tailSet(E fromElement) {
return new UnmodifiableSortedSet<>(ss.tailSet(fromElement));
} public E first() {return ss.first();}
public E last() {return ss.last();}
} // Synch Wrappers /**
* Returns a synchronized (thread-safe) collection backed by the specified
* collection. In order to guarantee serial access, it is critical that
* <strong>all</strong> access to the backing collection is accomplished
* through the returned collection.<p>
*
* It is imperative that the user manually synchronize on the returned
* collection when traversing it via {@link Iterator}, {@link Spliterator}
* or {@link Stream}:
* <pre>
* Collection c = Collections.synchronizedCollection(myCollection);
* ...
* synchronized (c) {
* Iterator i = c.iterator(); // Must be in the synchronized block
* while (i.hasNext())
* foo(i.next());
* }
* </pre>
* Failure to follow this advice may result in non-deterministic behavior.
*
* <p>The returned collection does <i>not</i> pass the {@code hashCode}
* and {@code equals} operations through to the backing collection, but
* relies on {@code Object}'s equals and hashCode 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 <T> the class of the objects in the collection
* @param c the collection to be "wrapped" in a synchronized collection.
* @return a synchronized view of the specified collection.
*/
//返回指定 collection 支持的同步(线程安全的)collection。
//为了保证按顺序访问,必须通过返回的 collection 完成所有对底层实现 collection 的访问。
public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
return new SynchronizedCollection<>(c);
} static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {
return new SynchronizedCollection<>(c, mutex);
} /**
* @serial include
*/
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L; final Collection<E> c; // Backing Collection
final Object mutex; // Object on which to synchronize SynchronizedCollection(Collection<E> c) {
this.c = Objects.requireNonNull(c);
mutex = this;
} SynchronizedCollection(Collection<E> c, Object mutex) {
this.c = Objects.requireNonNull(c);
this.mutex = Objects.requireNonNull(mutex);
} public int size() {
synchronized (mutex) {return c.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return c.isEmpty();}
}
public boolean contains(Object o) {
synchronized (mutex) {return c.contains(o);}
}
public Object[] toArray() {
synchronized (mutex) {return c.toArray();}
}
public <T> T[] toArray(T[] a) {
synchronized (mutex) {return c.toArray(a);}
} public Iterator<E> iterator() {
return c.iterator(); // Must be manually synched by user!
} public boolean add(E e) {
synchronized (mutex) {return c.add(e);}
}
public boolean remove(Object o) {
synchronized (mutex) {return c.remove(o);}
} public boolean containsAll(Collection<?> coll) {
synchronized (mutex) {return c.containsAll(coll);}
}
public boolean addAll(Collection<? extends E> coll) {
synchronized (mutex) {return c.addAll(coll);}
}
public boolean removeAll(Collection<?> coll) {
synchronized (mutex) {return c.removeAll(coll);}
}
public boolean retainAll(Collection<?> coll) {
synchronized (mutex) {return c.retainAll(coll);}
}
public void clear() {
synchronized (mutex) {c.clear();}
}
public String toString() {
synchronized (mutex) {return c.toString();}
}
// Override default methods in Collection
@Override
public void forEach(Consumer<? super E> consumer) {
synchronized (mutex) {c.forEach(consumer);}
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
synchronized (mutex) {return c.removeIf(filter);}
}
@Override
public Spliterator<E> spliterator() {
return c.spliterator(); // Must be manually synched by user!
}
@Override
public Stream<E> stream() {
return c.stream(); // Must be manually synched by user!
}
@Override
public Stream<E> parallelStream() {
return c.parallelStream(); // Must be manually synched by user!
}
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {s.defaultWriteObject();}
}
} // Dynamically typesafe collection wrappers /**
* Returns a dynamically typesafe view of the specified collection.
* Any attempt to insert an element of the wrong type will result in an
* immediate {@link ClassCastException}. Assuming a collection
* contains no incorrectly typed elements prior to the time a
* dynamically typesafe view is generated, and that all subsequent
* access to the collection takes place through the view, it is
* <i>guaranteed</i> that the collection cannot contain an incorrectly
* typed element.
*
* <p>The generics mechanism in the language provides compile-time
* (static) type checking, but it is possible to defeat this mechanism
* with unchecked casts. Usually this is not a problem, as the compiler
* issues warnings on all such unchecked operations. There are, however,
* times when static type checking alone is not sufficient. For example,
* suppose a collection is passed to a third-party library and it is
* imperative that the library code not corrupt the collection by
* inserting an element of the wrong type.
*
* <p>Another use of dynamically typesafe views is debugging. Suppose a
* program fails with a {@code ClassCastException}, indicating that an
* incorrectly typed element was put into a parameterized collection.
* Unfortunately, the exception can occur at any time after the erroneous
* element is inserted, so it typically provides little or no information
* as to the real source of the problem. If the problem is reproducible,
* one can quickly determine its source by temporarily modifying the
* program to wrap the collection with a dynamically typesafe view.
* For example, this declaration:
* <pre> {@code
* Collection<String> c = new HashSet<>();
* }</pre>
* may be replaced temporarily by this one:
* <pre> {@code
* Collection<String> c = Collections.checkedCollection(
* new HashSet<>(), String.class);
* }</pre>
* Running the program again will cause it to fail at the point where
* an incorrectly typed element is inserted into the collection, clearly
* identifying the source of the problem. Once the problem is fixed, the
* modified declaration may be reverted back to the original.
*
* <p>The returned collection does <i>not</i> pass the hashCode and equals
* operations through to the backing collection, but relies on
* {@code Object}'s {@code equals} and {@code hashCode} 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.
*
* <p>Since {@code null} is considered to be a value of any reference
* type, the returned collection permits insertion of null elements
* whenever the backing collection does.
*
* @param <E> the class of the objects in the collection
* @param c the collection for which a dynamically typesafe view is to be
* returned
* @param type the type of element that {@code c} is permitted to hold
* @return a dynamically typesafe view of the specified collection
* @since 1.5
*/
//返回指定 collection 的一个动态类型安全视图。用以检测元素类型是否正确。
public static <E> Collection<E> checkedCollection(Collection<E> c,
Class<E> type) {
return new CheckedCollection<>(c, type);
} @SuppressWarnings("unchecked")
static <T> T[] zeroLengthArray(Class<T> type) {
return (T[]) Array.newInstance(type, 0);
} /**
* @serial include
*/
static class CheckedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 1578914078182001775L; final Collection<E> c;
final Class<E> type; @SuppressWarnings("unchecked")
E typeCheck(Object o) {
if (o != null && !type.isInstance(o))
throw new ClassCastException(badElementMsg(o));
return (E) o;
} private String badElementMsg(Object o) {
return "Attempt to insert " + o.getClass() +
" element into collection with element type " + type;
} CheckedCollection(Collection<E> c, Class<E> type) {
this.c = Objects.requireNonNull(c, "c");
this.type = Objects.requireNonNull(type, "type");
} public int size() { return c.size(); }
public boolean isEmpty() { return c.isEmpty(); }
public boolean contains(Object o) { return c.contains(o); }
public Object[] toArray() { return c.toArray(); }
public <T> T[] toArray(T[] a) { return c.toArray(a); }
public String toString() { return c.toString(); }
public boolean remove(Object o) { return c.remove(o); }
public void clear() { c.clear(); } public boolean containsAll(Collection<?> coll) {
return c.containsAll(coll);
}
public boolean removeAll(Collection<?> coll) {
return c.removeAll(coll);
}
public boolean retainAll(Collection<?> coll) {
return c.retainAll(coll);
} public Iterator<E> iterator() {
// JDK-6363904 - unwrapped iterator could be typecast to
// ListIterator with unsafe set()
final Iterator<E> it = c.iterator();
return new Iterator<E>() {
public boolean hasNext() { return it.hasNext(); }
public E next() { return it.next(); }
public void remove() { it.remove(); }};
} public boolean add(E e) { return c.add(typeCheck(e)); } private E[] zeroLengthElementArray; // Lazily initialized private E[] zeroLengthElementArray() {
return zeroLengthElementArray != null ? zeroLengthElementArray :
(zeroLengthElementArray = zeroLengthArray(type));
} @SuppressWarnings("unchecked")
Collection<E> checkedCopyOf(Collection<? extends E> coll) {
Object[] a;
try {
E[] z = zeroLengthElementArray();
a = coll.toArray(z);
// Defend against coll violating the toArray contract
if (a.getClass() != z.getClass())
a = Arrays.copyOf(a, a.length, z.getClass());
} catch (ArrayStoreException ignore) {
// To get better and consistent diagnostics,
// we call typeCheck explicitly on each element.
// We call clone() to defend against coll retaining a
// reference to the returned array and storing a bad
// element into it after it has been type checked.
a = coll.toArray().clone();
for (Object o : a)
typeCheck(o);
}
// A slight abuse of the type system, but safe here.
return (Collection<E>) Arrays.asList(a);
} public boolean addAll(Collection<? extends E> coll) {
// Doing things this way insulates us from concurrent changes
// in the contents of coll and provides all-or-nothing
// semantics (which we wouldn't get if we type-checked each
// element as we added it)
return c.addAll(checkedCopyOf(coll));
} // Override default methods in Collection
@Override
public void forEach(Consumer<? super E> action) {c.forEach(action);}
@Override
public boolean removeIf(Predicate<? super E> filter) {
return c.removeIf(filter);
}
@Override
public Spliterator<E> spliterator() {return c.spliterator();}
@Override
public Stream<E> stream() {return c.stream();}
@Override
public Stream<E> parallelStream() {return c.parallelStream();}
} /**
* Returns an immutable list containing only the specified object.
* The returned list is serializable.
*
* @param <T> the class of the objects in the list
* @param o the sole object to be stored in the returned list.
* @return an immutable list containing only the specified object.
* @since 1.3
*/
//返回一个只包含指定对象的不可变列表。返回的列表是可序列化的。
public static <T> List<T> singletonList(T o) {
return new SingletonList<>(o);
} /**
* @serial include
*/
private static class SingletonList<E>
extends AbstractList<E>
implements RandomAccess, Serializable { private static final long serialVersionUID = 3093736618740652951L; private final E element; SingletonList(E obj) {element = obj;} public Iterator<E> iterator() {
return singletonIterator(element);
} public int size() {return 1;} public boolean contains(Object obj) {return eq(obj, element);} public E get(int index) {
if (index != 0)
throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
return element;
} // Override default methods for Collection
@Override
public void forEach(Consumer<? super E> action) {
action.accept(element);
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
throw new UnsupportedOperationException();
}
@Override
public void sort(Comparator<? super E> c) {
}
@Override
public Spliterator<E> spliterator() {
return singletonSpliterator(element);
}
} // Miscellaneous /**
* Returns an immutable list consisting of <tt>n</tt> copies of the
* specified object. The newly allocated data object is tiny (it contains
* a single reference to the data object). This method is useful in
* combination with the <tt>List.addAll</tt> method to grow lists.
* The returned list is serializable.
*
* @param <T> the class of the object to copy and of the objects
* in the returned list.
* @param n the number of elements in the returned list.
* @param o the element to appear repeatedly in the returned list.
* @return an immutable list consisting of <tt>n</tt> copies of the
* specified object.
* @throws IllegalArgumentException if {@code n < 0}
* @see List#addAll(Collection)
* @see List#addAll(int, Collection)
*/
//返回由指定对象的 n 个副本组成的不可变列表。
//新分配的数据对象非常小(它只包含一个对该数据对象的引用)。在通过与 List.addAll 方法组合来增大列表时,此方法很有用
public static <T> List<T> nCopies(int n, T o) {
if (n < 0)
throw new IllegalArgumentException("List length = " + n);
return new CopiesList<>(n, o);
} /**
* @serial include
*/
private static class CopiesList<E>
extends AbstractList<E>
implements RandomAccess, Serializable
{
private static final long serialVersionUID = 2739099268398711800L; final int n;
final E element; CopiesList(int n, E e) {
assert n >= 0;
this.n = n;
element = e;
} public int size() {
return n;
} public boolean contains(Object obj) {
return n != 0 && eq(obj, element);
} public int indexOf(Object o) {
return contains(o) ? 0 : -1;
} public int lastIndexOf(Object o) {
return contains(o) ? n - 1 : -1;
} public E get(int index) {
if (index < 0 || index >= n)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+n);
return element;
} public Object[] toArray() {
final Object[] a = new Object[n];
if (element != null)
Arrays.fill(a, 0, n, element);
return a;
} @SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
final int n = this.n;
if (a.length < n) {
a = (T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), n);
if (element != null)
Arrays.fill(a, 0, n, element);
} else {
Arrays.fill(a, 0, n, element);
if (a.length > n)
a[n] = null;
}
return a;
} public List<E> subList(int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > n)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
return new CopiesList<>(toIndex - fromIndex, element);
} // Override default methods in Collection
@Override
public Stream<E> stream() {
return IntStream.range(0, n).mapToObj(i -> element);
} @Override
public Stream<E> parallelStream() {
return IntStream.range(0, n).parallel().mapToObj(i -> element);
} @Override
public Spliterator<E> spliterator() {
return stream().spliterator();
}
} /**
* Returns a comparator that imposes the reverse of the <em>natural
* ordering</em> on a collection of objects that implement the
* {@code Comparable} interface. (The natural ordering is the ordering
* imposed by the objects' own {@code compareTo} method.) This enables a
* simple idiom for sorting (or maintaining) collections (or arrays) of
* objects that implement the {@code Comparable} interface in
* reverse-natural-order. For example, suppose {@code a} is an array of
* strings. Then: <pre>
* Arrays.sort(a, Collections.reverseOrder());
* </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
*
* The returned comparator is serializable.
*
* @param <T> the class of the objects compared by the comparator
* @return A comparator that imposes the reverse of the <i>natural
* ordering</i> on a collection of objects that implement
* the <tt>Comparable</tt> interface.
* @see Comparable
*/
//返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
@SuppressWarnings("unchecked")
public static <T> Comparator<T> reverseOrder() {
return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
} /**
* @serial include
*/
private static class ReverseComparator
implements Comparator<Comparable<Object>>, Serializable { private static final long serialVersionUID = 7207038068494060240L; static final ReverseComparator REVERSE_ORDER
= new ReverseComparator(); public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c2.compareTo(c1);
} private Object readResolve() { return Collections.reverseOrder(); } @Override
public Comparator<Comparable<Object>> reversed() {
return Comparator.naturalOrder();
}
} /**
* Returns a comparator that imposes the reverse ordering of the specified
* comparator. If the specified comparator is {@code null}, this method is
* equivalent to {@link #reverseOrder()} (in other words, it returns a
* comparator that imposes the reverse of the <em>natural ordering</em> on
* a collection of objects that implement the Comparable interface).
*
* <p>The returned comparator is serializable (assuming the specified
* comparator is also serializable or {@code null}).
*
* @param <T> the class of the objects compared by the comparator
* @param cmp a comparator who's ordering is to be reversed by the returned
* comparator or {@code null}
* @return A comparator that imposes the reverse ordering of the
* specified comparator.
* @since 1.5
*/
//返回一个比较器,它强行逆转指定比较器的顺序。
public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
if (cmp == null)
return reverseOrder(); if (cmp instanceof ReverseComparator2)
return ((ReverseComparator2<T>)cmp).cmp; return new ReverseComparator2<>(cmp);
} /**
* @serial include
*/
private static class ReverseComparator2<T> implements Comparator<T>,
Serializable
{
private static final long serialVersionUID = 4374092139857L; /**
* The comparator specified in the static factory. This will never
* be null, as the static factory returns a ReverseComparator
* instance if its argument is null.
*
* @serial
*/
final Comparator<T> cmp; ReverseComparator2(Comparator<T> cmp) {
assert cmp != null;
this.cmp = cmp;
} public int compare(T t1, T t2) {
return cmp.compare(t2, t1);
} public boolean equals(Object o) {
return (o == this) ||
(o instanceof ReverseComparator2 &&
cmp.equals(((ReverseComparator2)o).cmp));
} public int hashCode() {
return cmp.hashCode() ^ Integer.MIN_VALUE;
} @Override
public Comparator<T> reversed() {
return cmp;
}
} /**
* Returns an array list containing the elements returned by the
* specified enumeration in the order they are returned by the
* enumeration. This method provides interoperability between
* legacy APIs that return enumerations and new APIs that require
* collections.
*
* @param <T> the class of the objects returned by the enumeration
* @param e enumeration providing elements for the returned
* array list
* @return an array list containing the elements returned
* by the specified enumeration.
* @since 1.4
* @see Enumeration
* @see ArrayList
*/
public static <T> ArrayList<T> list(Enumeration<T> e) {
ArrayList<T> l = new ArrayList<>();
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
} /**
* Returns the number of elements in the specified collection equal to the
* specified object. More formally, returns the number of elements
* <tt>e</tt> in the collection such that
* <tt>(o == null ? e == null : o.equals(e))</tt>.
*
* @param c the collection in which to determine the frequency
* of <tt>o</tt>
* @param o the object whose frequency is to be determined
* @return the number of elements in {@code c} equal to {@code o}
* @throws NullPointerException if <tt>c</tt> is null
* @since 1.5
*/
//返回指定 collection 中等于指定对象的元素数。
//更确切地讲,返回 collection 中满足 (o == null ? e == null : o.equals(e)) 的 e 元素的数量。
public static int frequency(Collection<?> c, Object o) {
int result = 0;
if (o == null) {
for (Object e : c)
if (e == null)
result++;
} else {
for (Object e : c)
if (o.equals(e))
result++;
}
return result;
} /**
* Returns {@code true} if the two specified collections have no
* elements in common.
*
* <p>Care must be exercised if this method is used on collections that
* do not comply with the general contract for {@code Collection}.
* Implementations may elect to iterate over either collection and test
* for containment in the other collection (or to perform any equivalent
* computation). If either collection uses a nonstandard equality test
* (as does a {@link SortedSet} whose ordering is not <em>compatible with
* equals</em>, or the key set of an {@link IdentityHashMap}), both
* collections must use the same nonstandard equality test, or the
* result of this method is undefined.
*
* <p>Care must also be exercised when using collections that have
* restrictions on the elements that they may contain. Collection
* implementations are allowed to throw exceptions for any operation
* involving elements they deem ineligible. For absolute safety the
* specified collections should contain only elements which are
* eligible elements for both collections.
*
* <p>Note that it is permissible to pass the same collection in both
* parameters, in which case the method will return {@code true} if and
* only if the collection is empty.
*
* @param c1 a collection
* @param c2 a collection
* @return {@code true} if the two specified collections have no
* elements in common.
* @throws NullPointerException if either collection is {@code null}.
* @throws NullPointerException if one collection contains a {@code null}
* element and {@code null} is not an eligible element for the other collection.
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if one collection contains an element that is
* of a type which is ineligible for the other collection.
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @since 1.5
*/ //如果两个指定 collection 中没有相同的元素,则返回 true。
//如果将此方法用在不符合 Collection 常规协定的 collection 上,则必须小心。
//实现可以在任一 collection 上进行迭代,测试元素是否包含在另一个 collection 中(或执行任何等效的计算)。
//如果任一 collection 使用了一个非标准的相等性测试(比如顺序不是与 equals 一致的 SortedSet,
//或者 IdentityHashMap 的键集),则两个 collection
//都必须使用相同的非标准相等性测试,否则此方法的结果是不确定的。
//注意,允许在两个参数中传递相同的 collection,在这种情况下,当且仅当 collection 为空时此方法返回 true。
public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
// The collection to be used for contains(). Preference is given to
// the collection who's contains() has lower O() complexity.
Collection<?> contains = c2;
// The collection to be iterated. If the collections' contains() impl
// are of different O() complexity, the collection with slower
// contains() will be used for iteration. For collections who's
// contains() are of the same complexity then best performance is
// achieved by iterating the smaller collection.
Collection<?> iterate = c1; // Performance optimization cases. The heuristics:
// 1. Generally iterate over c1.
// 2. If c1 is a Set then iterate over c2.
// 3. If either collection is empty then result is always true.
// 4. Iterate over the smaller Collection.
if (c1 instanceof Set) {
// Use c1 for contains as a Set's contains() is expected to perform
// better than O(N/2)
iterate = c2;
contains = c1;
} else if (!(c2 instanceof Set)) {
// Both are mere Collections. Iterate over smaller collection.
// Example: If c1 contains 3 elements and c2 contains 50 elements and
// assuming contains() requires ceiling(N/2) comparisons then
// checking for all c1 elements in c2 would require 75 comparisons
// (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring
// 100 comparisons (50 * ceiling(3/2)).
int c1size = c1.size();
int c2size = c2.size();
if (c1size == 0 || c2size == 0) {
// At least one collection is empty. Nothing will match.
return true;
} if (c1size > c2size) {
iterate = c2;
contains = c1;
}
} for (Object e : iterate) {
if (contains.contains(e)) {
// Found a common element. Collections are not disjoint.
return false;
}
} // No common elements were found.
return true;
} /**
* Returns a view of a {@link Deque} as a Last-in-first-out (Lifo)
* {@link Queue}. Method <tt>add</tt> is mapped to <tt>push</tt>,
* <tt>remove</tt> is mapped to <tt>pop</tt> and so on. This
* view can be useful when you would like to use a method
* requiring a <tt>Queue</tt> but you need Lifo ordering.
*
* <p>Each method invocation on the queue returned by this method
* results in exactly one method invocation on the backing deque, with
* one exception. The {@link Queue#addAll addAll} method is
* implemented as a sequence of {@link Deque#addFirst addFirst}
* invocations on the backing deque.
*
* @param <T> the class of the objects in the deque
* @param deque the deque
* @return the queue
* @since 1.6
*/
//以后进先出 (Lifo) Queue 的形式返回某个 Deque 的视图。
//方法 add 被映射到 push,remove 被映射到 pop 等等。
//在希望使用某一方法获取一个 Queue 并且需要它具有 Lifo 顺序时,此方法很有用。
//每次在此方法返回的队列上调用方法都将导致在底层实现队列上调用该方法一次,
并伴随一个异常。addAll 方法是作为底层实现队列上的 addFirst 调用序列实现的。
public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
return new AsLIFOQueue<>(deque);
} /**
* @serial include
*/
static class AsLIFOQueue<E> extends AbstractQueue<E>
implements Queue<E>, Serializable {
private static final long serialVersionUID = 1802017725587941708L;
private final Deque<E> q;
AsLIFOQueue(Deque<E> q) { this.q = q; }
public boolean add(E e) { q.addFirst(e); return true; }
public boolean offer(E e) { return q.offerFirst(e); }
public E poll() { return q.pollFirst(); }
public E remove() { return q.removeFirst(); }
public E peek() { return q.peekFirst(); }
public E element() { return q.getFirst(); }
public void clear() { q.clear(); }
public int size() { return q.size(); }
public boolean isEmpty() { return q.isEmpty(); }
public boolean contains(Object o) { return q.contains(o); }
public boolean remove(Object o) { return q.remove(o); }
public Iterator<E> iterator() { return q.iterator(); }
public Object[] toArray() { return q.toArray(); }
public <T> T[] toArray(T[] a) { return q.toArray(a); }
public String toString() { return q.toString(); }
public boolean containsAll(Collection<?> c) {return q.containsAll(c);}
public boolean removeAll(Collection<?> c) {return q.removeAll(c);}
public boolean retainAll(Collection<?> c) {return q.retainAll(c);}
// We use inherited addAll; forwarding addAll would be wrong // Override default methods in Collection
@Override
public void forEach(Consumer<? super E> action) {q.forEach(action);}
@Override
public boolean removeIf(Predicate<? super E> filter) {
return q.removeIf(filter);
}
@Override
public Spliterator<E> spliterator() {return q.spliterator();}
@Override
public Stream<E> stream() {return q.stream();}
@Override
public Stream<E> parallelStream() {return q.parallelStream();}
}
}
JDK1.8源码Collections的更多相关文章
- 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)
一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...
- JDK1.8源码阅读系列之三:Vector
本篇随笔主要描述的是我阅读 Vector 源码期间的对于 Vector 的一些实现上的个人理解,用于个人备忘,有不对的地方,请指出- 先来看一下 Vector 的继承图: 可以看出,Vector 的直 ...
- 【1】【JUC】JDK1.8源码分析之ArrayBlockingQueue,LinkedBlockingQueue
概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Co ...
- 【集合框架】JDK1.8源码分析HashSet && LinkedHashSet(八)
一.前言 分析完了List的两个主要类之后,我们来分析Set接口下的类,HashSet和LinkedHashSet,其实,在分析完HashMap与LinkedHashMap之后,再来分析HashSet ...
- 【集合框架】JDK1.8源码分析之HashMap(一) 转载
[集合框架]JDK1.8源码分析之HashMap(一) 一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化 ...
- 【集合框架】JDK1.8源码分析之ArrayList详解(一)
[集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...
- 集合之TreeSet(含JDK1.8源码分析)
一.前言 前面分析了Set接口下的hashSet和linkedHashSet,下面接着来看treeSet,treeSet的底层实现是基于treeMap的. 四个关注点在treeSet上的答案 二.tr ...
- 集合之LinkedHashSet(含JDK1.8源码分析)
一.前言 上篇已经分析了Set接口下HashSet,我们发现其操作都是基于hashMap的,接下来看LinkedHashSet,其底层实现都是基于linkedHashMap的. 二.linkedHas ...
- 集合之HashSet(含JDK1.8源码分析)
一.前言 我们已经分析了List接口下的ArrayList和LinkedList,以及Map接口下的HashMap.LinkedHashMap.TreeMap,接下来看的是Set接口下HashSet和 ...
随机推荐
- UIO,大页内存,CPU亲和性,NUMA机制等
Linux环境下的UIO(Userspace I/O) UIO 用户空间下驱动程序的支持机制.DPDK使用UIO机制使网卡驱动程序运行在用户态,并采用轮询和零拷贝方式从网卡收取报文,提高收发报文的性能 ...
- 初学Nutch之简介与安装
1.Nutch简介 Nutch是一个由Java实 现的,开放源代码(open-source)的web搜索引擎.主要用于收集网页数据,然后对其进行分析,建立索引,以提供相应的接口来对其网页数据进行 查询 ...
- jdk命令行工具:jstat与jmap
转自文章:http://blog.csdn.net/gzh0222/article/details/8538727 C:\Users\Administrator\Desktop>jstat -g ...
- LDAP的前世今生
上世界80年代,就有了LDAP的雏形. 我接触到最早的Windows系列的服务器,是Windows2000 Professional版本里可以加入ActiveDirectory,后来从Windows2 ...
- C语言入门:04.数据类型、常量、变量
一.数据 1.什么是数据 生活中时时刻刻都在跟数据打交道,比如体重数据.血压数据.股价数据等.在我们使用计算机的过程中,会接触到各种各样的数据,有文档数据.图片数据.视频数据,还有聊QQ时产生的文字数 ...
- 微信 小程序组件 加入购物车全套 one wxss
//1,wxss /*外部容器*/ .container { display: flex; flex-direction: column; align-items: center; justify-c ...
- Semantic Versioning Specification & 语义化版本
Semantic Versioning Specification & 语义化版本 Semantic Versioning Specification http://semver.org 16 ...
- linux 命令大全,我去
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...
- Django_终端打印原生SQL语句
打印所有的sql语句 在Django项目的settings.py文件中,在最后复制粘贴如下代码: LOGGING = { 'version': 1, 'disable_existing_loggers ...
- MT【98】三元对称不等式
评:这是一道浙江省省赛题,这里利用对称性,设$x\le y\le z$从而解决了问题.值得注意的是此处三元轮换对称正好也是完全对称,但如果变成一般的$n\ge4$元对称问题时,就不能设大小关系.事实上 ...