读书人

JDK源码解析 java.util.Collections种

发布时间: 2012-12-18 12:43:41 作者: rapoo

JDK源码解析 java.util.Collections类 jdk1.6

?

/*

?* @(#)Collections.java 1.106 06/04/21

?*

?* Copyright 2006 Sun Microsystems, Inc. All rights reserved.

?* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.

?*/

?

package java.util;

?

import java.io.Serializable;

import java.io.ObjectOutputStream;

import java.io.IOException;

import java.lang.reflect.Array;

?

/**

此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。?

?

如果为此类的方法所提供的 collection 或类对象为 null,则这些方法都将抛出 NullPointerException。?

?

此类中所含多态算法的文档通常包括对实现 的简短描述。应该将这类描述视为实现注意事项,而不是规范 的一部分。实现者应该可以随意使用其他算法替代,只要遵循规范本身即可。(例如,sort 使用的算法不一定是合并排序算法,但它必须是稳定的。)?

?

此类中包含的“破坏性”算法,即可修改其所操作的 collection 的算法,该算法被指定在 collection 不支持适当的可变基元(比如 set 方法)时抛出 UnsupportedOperationException。如果调用不会对 collection 产生任何影响,那么这些算法可能(但不要求)抛出此异常。例如,在已经排序的、不可修改列表上调用 sort 方法可能会(也可能不会)抛出 UnsupportedOperationException。?

?

此类是 Java Collections Framework 的成员。?

?

?

?

从以下版本开始:?

1.2?

另请参见:

Collection, Set, List, Map

?

?*/

?

? //Collections中有许多静态的内部类,用于构造特定的集合对象。

?

public class Collections { //Collections类是操作collection集合的工具类。提供很多静态的方法供使用。

// 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; //子列索引的临界值

?

/**

根据元素的自然顺序 对指定列表按升序进行排序。列表中的所有元素都必须实现 Comparable 接口。此外,列表中的所有元素都必须是可相互比较的(也就是说,对于列表中的任何 e1 和 e2 元素,e1.compareTo(e2) 不得抛出 ClassCastException)。

此排序方法具有稳定性:不会因调用 sort 方法而对相等的元素进行重新排序。

?

指定列表必须是可修改的,但不必是大小可调整的。

?

该排序算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)。此算法提供可保证的 n log(n) 性能。 此实现将指定列表转储到一个数组中,并对数组进行排序,在重置数组中相应位置处每个元素的列表上进行迭代。这避免了由于试图原地对链接列表进行排序而产生的 n2 log(n) 性能。?

?

?

参数:

list - 要排序的列表。?

抛出:?

ClassCastException - 如果列表包含不可相互比较 的元素(例如,字符串和整数)。?

UnsupportedOperationException - 如果指定列表的列表迭代器不支持 set 操作。

另请参见:

Comparable

?

*/

public static <T extends Comparable<? super T>> void sort(List<T> list) {

Object[] a = list.toArray(); //将传入的List转换为一个Object类型的数组。

Arrays.sort(a); //调用Arrays的sort方法进行排序。

ListIterator<T> i = list.listIterator(); //获取传入的List的迭代器对象

for (int j = 0; j < a.length; j++) { //使用迭代器,将排序好的值重新设置到List中

i.next();

i.set((T) a[j]);

}

}

?

/**

根据指定比较器产生的顺序对指定列表进行排序。此列表内的所有元素都必须可使用指定比较器相互比较(也就是说,对于列表中的任意 e1 和 e2 元素,c.compare(e1, e2) 不得抛出 ClassCastException)。

此排序被保证是稳定的:不会因调用 sort 而对相等的元素进行重新排序。

?

排序算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)。此算法提供可保证的 n log(n) 性能。 指定列表必须是可修改的,但不必是可大小调整的。此实现将指定列表转储到一个数组中,并对数组进行排序,在重置数组中相应位置每个元素的列表上进行迭代。这避免了由于试图原地对链接列表进行排序而产生的 n2 log(n) 性能。?

?

?

参数:

list - 要排序的列表。

c - 确定列表顺序的比较器。null 值指示应该使用元素的自然顺序。?

抛出:?

ClassCastException - 如果列表中包含不可使用指定比较器相互比较 的元素。?

UnsupportedOperationException - 如果指定列表的列表迭代器不支持 set 操作。

另请参见:

Comparator

?

*/

public static <T> void sort(List<T> list, Comparator<? super T> c) {

Object[] a = list.toArray(); //将传入的List对象转换为一个Object的数组

Arrays.sort(a, (Comparator) c); //调用Arrays的sort方法,传入比较器进行排序

ListIterator i = list.listIterator();

for (int j = 0; j < a.length; j++) {

i.next();

i.set(a[j]);

}

}

?

/**

使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过 sort(List) 方法)。如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。?

此方法对“随机访问”列表运行 log(n) 次(它提供接近固定时间的位置访问)。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此方法将执行基于迭代器的二分搜索,执行 O(n) 次链接遍历和 O(log n) 次元素比较。?

?

?

参数:

list - 要搜索的列表。

key - 要搜索的键。?

返回:

如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。?

抛出:?

ClassCastException - 如果列表中包含不可相互比较 的元素(例如,字符串和整数),或者搜索键无法与列表的元素进行相互比较。

?

*/

public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {

if (list instanceof RandomAccess || list.size() < BINARYSEARCH_THRESHOLD) //如果传入的List是RandomAccess的实例,或者List的大小小于二分查找的临界值,那么调用Collections的indexedBinarySearch方法,否则调用Collections的iteratorBinarySearch方法。

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; //取中间索引值,这里的>>>其实跟除以2一样,只不过速度更快。

Comparable<? super T> midVal = list.get(mid); //取得中间值

int cmp = midVal.compareTo(key); //调用compareTo进行比较

?

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(); //取得List的迭代器

?

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;

}

?

/**

使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据指定的比较器对列表进行升序排序(通过 sort(List, Comparator) 方法)。如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。?

此方法对“随机访问”的列表运行 log(n) 次(它提供接近固定时间的位置访问)。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此方法将执行基于迭代器的二分搜索,执行 O(n) 次链接遍历和 O(log n) 次元素比较。?

?

?

参数:

list - 要搜索的列表。

key - 要搜索的键。

c - 排序列表的比较器。null 值指示应该使用元素的自然顺序。?

返回:

如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。?

抛出:?

ClassCastException - 如果列表中包含使用指定的比较器不可相互比较 的元素,或者使用此比较器无法相互比较搜索键与列表元素。

?

*/

public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {

if (c == null)

return binarySearch((List) list, key);

?

if (list instanceof RandomAccess || list.size() < BINARYSEARCH_THRESHOLD)

return Collections.indexedBinarySearch(list, key, c);

else

return Collections.iteratorBinarySearch(list, key, c);

}

?

private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {

int low = 0;

int high = l.size() - 1;

?

while (low <= high) {

int mid = (low + high) >>> 1;

T midVal = l.get(mid);

int cmp = c.compare(midVal, key);

?

if (cmp < 0)

low = mid + 1;

else if (cmp > 0)

high = mid - 1;

else

return mid; // key found

}

return -(low + 1); // key not found

}

?

private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {

int low = 0;

int high = l.size() - 1;

ListIterator<? extends T> i = l.listIterator();

?

while (low <= high) {

int mid = (low + high) >>> 1;

T midVal = get(i, mid);

int cmp = c.compare(midVal, key);

?

if (cmp < 0)

low = mid + 1;

else if (cmp > 0)

high = mid - 1;

else

return mid; // key found

}

return -(low + 1); // key not found

}

?

//内部接口

private interface SelfComparable extends Comparable<SelfComparable> {

}

?

/**

反转指定列表中元素的顺序。

此方法以线性时间运行。?

?

?

参数:

list - 元素要被反转的列表。?

抛出:?

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

?

*/

public static void reverse(List<?> list) {

int size = list.size(); //取得List的大小

if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { //如果List的大小小于反转临界值,或者List是RandomAccess的实例

for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) //遍历并反转List里的元素

swap(list, i, j);

} else { //否则,使用迭代器来反转

ListIterator fwd = list.listIterator();

ListIterator rev = list.listIterator(size);

for (int i = 0, mid = list.size() >> 1; i < mid; i++) {

Object tmp = fwd.next();

fwd.set(rev.previous());

rev.set(tmp);

}

}

}

?

/**

使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。

前面描述中使用了不确定的词“大致”,因为随机源只是大致上独立选择位的无偏源。如果它是一个随机选择位的最佳源,那么算法将完全一致的选择置换。

?

此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。

?

此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到数组中,并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。?

?

?

参数:

list - 要改组的列表。?

抛出:?

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

?

*/

public static void shuffle(List<?> list) { //这个方法相当于洗牌

if (r == null) {

r = new Random();

}

shuffle(list, r);

}

?

private static Random r; //随机对象

?

/**

使用指定的随机源对指定列表进行置换。所有置换发生的可能性都是相等的,假定随机源是公平的。

此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。

?

此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到一个数组中,并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。?

?

?

参数:

list - 要改组的列表。

rnd - 用来改组列表的随机源。?

抛出:?

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

?

*/

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

ListIterator it = list.listIterator();

for (int i = 0; i < arr.length; i++) {

it.next();

it.set(arr[i]);

}

}

}

?

/**

在指定列表的指定位置处交换元素。(如果指定位置相同,则调用此方法不会更改列表。)?

?

参数:

list - 进行元素交换的列表。

i - 要交换的一个元素的索引。

j - 要交换的另一个元素的索引。?

抛出:?

IndexOutOfBoundsException - 如果 i 或 j 超出范围 (i < 0 || i >= list.size() || j < 0 || j >= list.size())。

从以下版本开始:?

1.4?

?

* @since 1.4

*/

public static void swap(List<?> list, int i, int j) {

final List l = list;

l.set(i, l.set(j, l.get(i))); //将i和j位置上的元素交换,只是调用了set和get方法。

}

?

/**

* 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;

}

?

/**

使用指定元素替换指定列表中的所有元素。?

此方法以线性时间运行。?

?

?

参数:

list - 使用指定元素填充的列表。

obj - 用来填充指定列表的元素。?

抛出:?

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

?

*/

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);

}

}

}

?

/**

将所有元素从一个列表复制到另一个列表。执行此操作后,目标列表中每个已复制元素的索引将等同于源列表中该元素的索引。目标列表的长度至少必须等于源列表。如果目标列表更长一些,也不会影响目标列表中的其余元素。

此方法以线性时间运行。?

?

?

参数:

dest - 目标列表。

src - 源列表。?

抛出:?

IndexOutOfBoundsException - 如果目标列表太小而无法包含整个源列表。?

UnsupportedOperationException - 如果目标列表的列表迭代器不支持 set 操作。

?

*/

public static <T> void copy(List<? super T> dest, List<? extends T> src) {

int srcSize = src.size();

if (srcSize > dest.size()) //可以看到,目标List的大小不能小于源List的大小。否则元素放不进去。

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)); //还是调用set和get方法

} 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());

}

}

}

?

/**

根据元素的自然顺序 返回给定 collection 的最小元素。collection 中的所有元素都必须实现 Comparable 接口。此外,collection 中的所有元素都必须是可相互比较的(也就是说,对于 collection 中的任意 e1 和 e2 元素,e1.compareTo(e2) 不得抛出 ClassCastException)。

此方法在整个 collection 上进行迭代,所以它需要的时间与 collection 的大小成正比。?

?

?

参数:

coll - 将确定其最小元素的 collection。?

返回:

根据元素的自然顺序,返回给定 collection 的最小元素。?

抛出:?

ClassCastException - 如果 collection 包含不可相互比较 的元素(例如,字符串和整数)。?

NoSuchElementException - 如果 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; //迭代List,将小的元素赋值给candidate,迭代完之后,candidate就是最小值。

}

return candidate;

}

?

/**

根据指定比较器产生的顺序,返回给定 collection 的最小元素。collection 中的所有元素都必须可通过指定比较器相互比较(也就是说,对于 collection 中的任意 e1 和 e2 元素,comp.compare(e1, e2) 不得抛出 ClassCastException)。

此方法在整个 collection 上进行迭代,所以它需要的时间与 collection 的大小成正比。?

?

?

参数:

coll - 将确定其最小元素的 collection。

comp - 用来确定最小元素的比较器。null 值指示应该使用元素的自然顺序。?

返回:

根据指定比较器返回给定 collection 的最小元素。?

抛出:?

ClassCastException - 如果 collection 中包含不可使用指定比较器相互比较 的元素。?

NoSuchElementException - 如果 collection 为空。

另请参见:

Comparable

?

*/

public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {

if (comp == null)

return (T) min((Collection<SelfComparable>) (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;

}

?

/**

根据元素的自然顺序,返回给定 collection 的最大元素。collection 中的所有元素都必须实现 Comparable 接口。此外,collection 中的所有元素都必须是可相互比较的(也就是说,对于 collection 中的任意 e1 和 e2 元素,e1.compareTo(e2) 不得抛出 ClassCastException)。

此方法在整个 collection 上进行迭代,所以它需要的时间与 collection 的大小成正比。?

?

?

参数:

coll - 将确定其最大元素的 collection。?

返回:

根据元素的自然顺序 返回给定 collection 的最大元素。?

抛出:?

ClassCastException - 如果 collection 包含不可相互比较 的元素(例如,字符串和整数)。?

NoSuchElementException - 如果 collection 为空。

另请参见:

Comparable

?

*/

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;

}

?

/**

根据指定比较器产生的顺序,返回给定 collection 的最大元素。collection 中的所有元素都必须可通过指定比较器相互比较(也就是说,对于 collection 中的任意 e1 和 e2 元素,comp.compare(e1, e2) 不得抛出 ClassCastException)。

此方法在整个 collection 上进行迭代,所以它需要的时间与 collection 的大小成正比。?

?

?

参数:

coll - 将确定其最大元素的 collection。

comp - 用来确定最大元素的比较器。null 值指示应该使用元素的自然顺序。?

返回:

根据指定比较器返回给定 collection 的最大元素。?

抛出:?

ClassCastException - 如果 collection 中包含不可使用指定比较器相互比较 的元素。?

NoSuchElementException - 如果 collection 为空。

另请参见:

Comparable

?

*/

public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {

if (comp == null)

return (T) max((Collection<SelfComparable>) (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;

}

?

/**

根据指定的距离轮换指定列表中的元素。调用此方法后,对于 0 和 list.size()-1(包括)之间的所有 i 值,索引 i 处的元素将是以前位于索引 (i - distance) mod list.size() 处的元素。(此方法对列表的大小没有任何影响。)?

例如,假设 list 包含 [t, a, n, k, s]。在调用 Collections.rotate(list, 1)(或 Collections.rotate(list, -4))之后,list 将包含 [s, t, a, n, k]。?

?

注意,此方法用于子列表时非常有用,可以在保留其余元素顺序的同时,在列表中移动一个或多个元素。例如,以下语句可以将索引 j 处的元素向前移动到位置 k 上(k 必须大于等于 j):?

?

? ? Collections.rotate(list.subList(j, k+1), -1);

为了具体说明这一点,假设 list 包含 [a, b, c, d, e]。要将索引 1 处的元素(b)向前移动两个位置,请执行以下调用:?

? ? Collections.rotate(l.subList(1, 4), -1);

得到的列表是 [a, c, d, b, e]。?

要将多个元素向前移动,则需要增加循环移动距离的绝对值。要将元素向后移动,请使用一个正的移动距离。?

?

如果指定列表是一个小型列表,或者它实现了 RandomAccess 接口,则此实现会将第一个元素交换到它应该去的位置上,然后重复执行交换操作,将替换的元素交换到它们应该去的位置上,直到替换的元素交换成第一个元素。如有必要,需要在第二个或后续元素上重复这个过程,直到完成轮换。如果指定的列表是大型列表并且没有实现 RandomAccess 接口,则此实现会将列表拆分成位于 -distance mod size 索引两边的两个子列表视图。然后在每个子列表视图上调用 reverse(List) 方法,并最终在整个列表上调用此方法。有关这两种算法更为完整的描述,请参阅 Jon Bentley 撰写的 Programming Pearls (Addison-Wesley, 1986) 一书中的第 2.3 小节。?

?

?

参数:

list - 要轮换的列表。

distance - 列表轮换的距离。在此值上没有任何限制;它可以是 0、负数或大于 list.size() 的数。?

抛出:?

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

从以下版本开始:?

1.4?

?

*/

public static void rotate(List<?> list, int distance) {

if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)

rotate1((List) list, distance);

else

rotate2((List) list, distance);

}

?

//轮换算法

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);

}

?

/**

使用另一个值替换列表中出现的所有某一指定值。更确切地讲,使用 newVal 替换 list 中满足 (oldVal==null ? e==null : oldVal.equals(e)) 的每个 e 元素。(此方法对列表的大小没有任何影响。)?

?

参数:

list - 在其中进行替换的列表。

oldVal - 将被替换的原值。

newVal - 替换 oldVal 的新值。?

返回:

如果 list 包含一个或多个满足 (oldVal==null ? e==null : oldVal.equals(e)) 的 e 元素,则返回 true。?

抛出:?

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

从以下版本开始:?

1.4?

?

*/

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;

}

?

/**

返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。更确切地讲,返回满足 source.subList(i, i+target.size()).equals(target) 的最低索引 i;如果不存在这样的索引,则返回 -1。(如果 target.size() > source.size(),则返回 -1。)?

此实现使用 "brute force" 扫描技术在源列表上进行扫描,依次在每个位置上寻找与目标匹配的列表项。?

?

?

参数:

source - 在该列表中搜索第一次出现的 target。

target - 作为 source 子列表搜索的列表。?

返回:

返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。

从以下版本开始:?

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

}

?

/**

返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。更确切地讲,返回满足 source.subList(i, i+target.size()).equals(target) 的最高索引 i;如果不存在这样的索引,则返回 -1。(如果 target.size() > source.size(),则返回 -1。)?

此实现使用 "brute force" 迭代技术在源列表上进行迭代,依次在每个位置上寻找与目标匹配的列表项。?

?

?

参数:

source - 在该列表中搜索最后一次出现的 target。

target - 作为 source 子列表搜索的列表。?

返回:

返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。

从以下版本开始:?

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

?

/**

返回指定 collection 的不可修改视图。此方法允许模块为用户提供对内部 collection 的“只读”访问。在返回的 collection 上执行的查询操作将“读完”指定的 collection。试图修改返回的 collection(不管是直接修改还是通过其迭代器进行修改)将导致抛出 UnsupportedOperationException。

返回的 collection 不会 将 hashCode 和 equals 操作传递给底层实现 collection,但这依赖于 Object 的 equals 和 hashCode 方法。在底层实现 collection 是一个 set 或是一个列表的情况下,有必要遵守这些操作的协定。

?

如果指定 collection 是可序列化的,则返回的 collection 也将是可序列化的。?

?

?

参数:

c - 将为其返回一个不可修改视图的 collection。?

返回:

指定 collection 的不可修改视图。

?

* @return an unmodifiable view of the specified collection.

*/

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {

return new UnmodifiableCollection<T>(c);

}

?

/**

* @serial include

* 内部类

*/

static class UnmodifiableCollection<E> implements Collection<E>, Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

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>() {

Iterator<? extends E> i = c.iterator();

?

public boolean hasNext() {

return i.hasNext();

}

?

public E next() {

return i.next();

}

?

public void remove() {

throw new UnsupportedOperationException();

}

};

}

?

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();

}

}

?

/**

返回指定 set 的不可修改视图。此方法允许模块为用户提供对内部 set 的“只读”访问。在返回的 set 上执行的查询操作将“读完”指定的 set。试图修改返回的 set(不管是直接修改还是通过其迭代器进行修改)将导致抛出 UnsupportedOperationException。

如果指定 set 是可序列化的,则返回的 set 也将是可序列化的。?

?

?

参数:

s - 将为其返回一个不可修改视图的 set。?

返回:

指定 set 的不可修改视图。

?

*/

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {

return new UnmodifiableSet<T>(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();

}

}

?

/**

返回指定有序 set 的不可修改视图。此方法允许模块为用户提供对内部有序 set 的“只读”访问。在返回的有序 set 上执行的查询操作将“读完”指定的有序 set。试图修改返回的有序 set(无论是直接修改、通过其迭代器修改,还是通过其 subSet、headSet 或 tailSet 视图修改)将导致抛出 UnsupportedOperationException。

如果指定有序 set 是可序列化的,则返回的有序 set 也将是可序列化的。?

?

?

参数:

s - 将为其返回一个不可修改视图的有序 set。?

返回:

指定有序 set 的不可修改视图。

?

*/

public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {

return new UnmodifiableSortedSet<T>(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<E>(ss.subSet(fromElement, toElement));

}

?

public SortedSet<E> headSet(E toElement) {

return new UnmodifiableSortedSet<E>(ss.headSet(toElement));

}

?

public SortedSet<E> tailSet(E fromElement) {

return new UnmodifiableSortedSet<E>(ss.tailSet(fromElement));

}

?

public E first() {

return ss.first();

}

?

public E last() {

return ss.last();

}

}

?

/**

返回指定列表的不可修改视图。此方法允许模块为用户提供对内部列表的“只读”访问。在返回的列表上执行的查询操作将“读完”指定的列表。试图修改返回的列表(不管是直接修改还是通过其迭代器进行修改)将导致抛出 UnsupportedOperationException。

如果指定列表是可序列化的,则返回的列表也将是可序列化的。类似地,如果指定列表实现 RandomAccess,则返回列表也将这样做。?

?

?

参数:

list - 将为其返回一个不可修改视图的列表。?

返回:

指定列表的不可修改视图。

?

*/

public static <T> List<T> unmodifiableList(List<? extends T> list) {

return (list instanceof RandomAccess ? new UnmodifiableRandomAccessList<T>(list)

: new UnmodifiableList<T>(list));

}

?

/**

* @serial include

*/

static class UnmodifiableList<E> extends UnmodifiableCollection<E> implements List<E> {

static final long serialVersionUID = -283967356065247728L;

final List<? extends E> list;

?

UnmodifiableList(List<? extends E> list) {

super(list);

this.list = list;

}

?

public boolean equals(Object o) {

return o == this || list.equals(o);

}

?

public int hashCode() {

return list.hashCode();

}

?

public E get(int index) {

return list.get(index);

}

?

public E set(int index, E element) {

throw new UnsupportedOperationException();

}

?

public void add(int index, E element) {

throw new UnsupportedOperationException();

}

?

public E remove(int index) {

throw new UnsupportedOperationException();

}

?

public int indexOf(Object o) {

return list.indexOf(o);

}

?

public int lastIndexOf(Object o) {

return list.lastIndexOf(o);

}

?

public boolean addAll(int index, Collection<? extends E> c) {

throw new UnsupportedOperationException();

}

?

public ListIterator<E> listIterator() {

return listIterator(0);

}

?

public ListIterator<E> listIterator(final int index) {

return new ListIterator<E>() {

ListIterator<? extends E> i = list.listIterator(index);

?

public boolean hasNext() {

return i.hasNext();

}

?

public E next() {

return i.next();

}

?

public boolean hasPrevious() {

return i.hasPrevious();

}

?

public E previous() {

return i.previous();

}

?

public int nextIndex() {

return i.nextIndex();

}

?

public int previousIndex() {

return i.previousIndex();

}

?

public void remove() {

throw new UnsupportedOperationException();

}

?

public void set(E e) {

throw new UnsupportedOperationException();

}

?

public void add(E e) {

throw new UnsupportedOperationException();

}

};

}

?

public List<E> subList(int fromIndex, int toIndex) {

return new UnmodifiableList<E>(list.subList(fromIndex, toIndex));

}

?

/**

* UnmodifiableRandomAccessList instances are serialized as

* UnmodifiableList instances to allow them to be deserialized

* in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).

* This method inverts the transformation. ?As a beneficial

* side-effect, it also grafts the RandomAccess marker onto

* UnmodifiableList instances that were serialized in pre-1.4 JREs.

*

* Note: Unfortunately, UnmodifiableRandomAccessList instances

* serialized in 1.4.1 and deserialized in 1.4 will become

* UnmodifiableList instances, as this method was missing in 1.4.

*/

private Object readResolve() {

return (list instanceof RandomAccess ? new UnmodifiableRandomAccessList<E>(list) : this);

}

}

?

/**

* @serial include

*/

static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E> implements RandomAccess {

UnmodifiableRandomAccessList(List<? extends E> list) {

super(list);

}

?

public List<E> subList(int fromIndex, int toIndex) {

return new UnmodifiableRandomAccessList<E>(list.subList(fromIndex, toIndex));

}

?

private static final long serialVersionUID = -2542308836966382001L;

?

/**

* Allows instances to be deserialized in pre-1.4 JREs (which do

* not have UnmodifiableRandomAccessList). ?UnmodifiableList has

* a readResolve method that inverts this transformation upon

* deserialization.

*/

private Object writeReplace() {

return new UnmodifiableList<E>(list);

}

}

?

/**

返回指定映射的不可修改视图。此方法允许模块为用户提供对内部映射的“只读”访问。在返回的映射上执行的查询操作将“读完”指定的映射。试图修改返回的映射(不管是直接修改还是通过其 collection 视图进行修改)将导致抛出 UnsupportedOperationException。

如果指定映射是可序列化的,则返回的映射也将是可序列化的。?

?

?

参数:

m - 将为其返回一个不可修改视图的映射。?

返回:

指定映射的不可修改视图。

?

*/

public static <K, V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m) {

return new UnmodifiableMap<K, V>(m);

}

?

/**

* @serial include

*/

private static class UnmodifiableMap<K, V> implements Map<K, V>, Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = -1034234728574286014L;

?

private final Map<? extends K, ? extends V> m;

?

UnmodifiableMap(Map<? extends K, ? extends V> m) {

if (m == null)

throw new NullPointerException();

this.m = m;

}

?

public int size() {

return m.size();

}

?

public boolean isEmpty() {

return m.isEmpty();

}

?

public boolean containsKey(Object key) {

return m.containsKey(key);

}

?

public boolean containsValue(Object val) {

return m.containsValue(val);

}

?

public V get(Object key) {

return m.get(key);

}

?

public V put(K key, V value) {

throw new UnsupportedOperationException();

}

?

public V remove(Object key) {

throw new UnsupportedOperationException();

}

?

public void putAll(Map<? extends K, ? extends V> m) {

throw new UnsupportedOperationException();

}

?

public void clear() {

throw new UnsupportedOperationException();

}

?

private transient Set<K> keySet = null;

private transient Set<Map.Entry<K, V>> entrySet = null;

private transient Collection<V> values = null;

?

public Set<K> keySet() {

if (keySet == null)

keySet = unmodifiableSet(m.keySet());

return keySet;

}

?

public Set<Map.Entry<K, V>> entrySet() {

if (entrySet == null)

entrySet = new UnmodifiableEntrySet<K, V>(m.entrySet());

return entrySet;

}

?

public Collection<V> values() {

if (values == null)

values = unmodifiableCollection(m.values());

return values;

}

?

public boolean equals(Object o) {

return o == this || m.equals(o);

}

?

public int hashCode() {

return m.hashCode();

}

?

public String toString() {

return m.toString();

}

?

/**

* We need this class in addition to UnmodifiableSet as

* Map.Entries themselves permit modification of the backing Map

* via their setValue operation. ?This class is subtle: there are

* many possible attacks that must be thwarted.

*

* @serial include

*/

static class UnmodifiableEntrySet<K, V> extends UnmodifiableSet<Map.Entry<K, V>> {

private static final long serialVersionUID = 7854390611657943733L;

?

UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {

super((Set) s);

}

?

public Iterator<Map.Entry<K, V>> iterator() {

return new Iterator<Map.Entry<K, V>>() {

Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();

?

public boolean hasNext() {

return i.hasNext();

}

?

public Map.Entry<K, V> next() {

return new UnmodifiableEntry<K, V>(i.next());

}

?

public void remove() {

throw new UnsupportedOperationException();

}

};

}

?

public Object[] toArray() {

Object[] a = c.toArray();

for (int i = 0; i < a.length; i++)

a[i] = new UnmodifiableEntry<K, V>((Map.Entry<K, V>) a[i]);

return a;

}

?

public <T> T[] toArray(T[] a) {

// We don't pass a to c.toArray, to avoid window of

// vulnerability wherein an unscrupulous multithreaded client

// could get his hands on raw (unwrapped) Entries from c.

Object[] arr = c.toArray(a.length == 0 ? a : Arrays.copyOf(a, 0));

?

for (int i = 0; i < arr.length; i++)

arr[i] = new UnmodifiableEntry<K, V>((Map.Entry<K, V>) arr[i]);

?

if (arr.length > a.length)

return (T[]) arr;

?

System.arraycopy(arr, 0, a, 0, arr.length);

if (a.length > arr.length)

a[arr.length] = null;

return a;

}

?

/**

* This method is overridden to protect the backing set against

* an object with a nefarious equals function that senses

* that the equality-candidate is Map.Entry and calls its

* setValue method.

*/

public boolean contains(Object o) {

if (!(o instanceof Map.Entry))

return false;

return c.contains(new UnmodifiableEntry<K, V>((Map.Entry<K, V>) o));

}

?

/**

* The next two methods are overridden to protect against

* an unscrupulous List whose contains(Object o) method senses

* when o is a Map.Entry, and calls o.setValue.

*/

public boolean containsAll(Collection<?> coll) {

Iterator<?> e = coll.iterator();

while (e.hasNext())

if (!contains(e.next())) // Invokes safe contains() above

return false;

return true;

}

?

public boolean equals(Object o) {

if (o == this)

return true;

?

if (!(o instanceof Set))

return false;

Set s = (Set) o;

if (s.size() != c.size())

return false;

return containsAll(s); // Invokes safe containsAll() above

}

?

/**

* This "wrapper class" serves two purposes: it prevents

* the client from modifying the backing Map, by short-circuiting

* the setValue method, and it protects the backing Map against

* an ill-behaved Map.Entry that attempts to modify another

* Map Entry when asked to perform an equality check.

*/

private static class UnmodifiableEntry<K, V> implements Map.Entry<K, V> {

private Map.Entry<? extends K, ? extends V> e;

?

UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {

this.e = e;

}

?

public K getKey() {

return e.getKey();

}

?

public V getValue() {

return e.getValue();

}

?

public V setValue(V value) {

throw new UnsupportedOperationException();

}

?

public int hashCode() {

return e.hashCode();

}

?

public boolean equals(Object o) {

if (!(o instanceof Map.Entry))

return false;

Map.Entry t = (Map.Entry) o;

return eq(e.getKey(), t.getKey()) && eq(e.getValue(), t.getValue());

}

?

public String toString() {

return e.toString();

}

}

}

}

?

/**

返回指定有序映射的不可修改视图。此方法允许模块为用户提供对内部有序映射的“只读”访问。在返回的有序映射上执行的查询操作将“读完”指定的有序映射。试图修改返回的有序映射(无论是直接修改、通过其 collection 视图修改,还是通过其 subMap、headMap 或 tailMap 视图修改)将导致抛出 UnsupportedOperationException。

如果指定的有序映射是可序列化的,则返回的有序映射也将是可序列化的。?

?

?

参数:

m - 将为其返回一个不可修改视图的有序映射。?

返回:

指定有序映射的不可修改视图。

?

*/

public static <K, V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {

return new UnmodifiableSortedMap<K, V>(m);

}

?

/**

* @serial include

*/

static class UnmodifiableSortedMap<K, V> extends UnmodifiableMap<K, V> implements SortedMap<K, V>, Serializable {

private static final long serialVersionUID = -8806743815996713206L;

?

private final SortedMap<K, ? extends V> sm;

?

UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {

super(m);

sm = m;

}

?

public Comparator<? super K> comparator() {

return sm.comparator();

}

?

public SortedMap<K, V> subMap(K fromKey, K toKey) {

return new UnmodifiableSortedMap<K, V>(sm.subMap(fromKey, toKey));

}

?

public SortedMap<K, V> headMap(K toKey) {

return new UnmodifiableSortedMap<K, V>(sm.headMap(toKey));

}

?

public SortedMap<K, V> tailMap(K fromKey) {

return new UnmodifiableSortedMap<K, V>(sm.tailMap(fromKey));

}

?

public K firstKey() {

return sm.firstKey();

}

?

public K lastKey() {

return sm.lastKey();

}

}

?

// Synch Wrappers

?

/**

返回指定 collection 支持的同步(线程安全的)collection。为了保证按顺序访问,必须通过返回的 collection 完成所有对底层实现 collection 的访问。

在返回的 collection 上进行迭代时,用户必须手工在返回的 collection 上进行同步:?

?

?Collection c = Collections.synchronizedCollection(myCollection);

? ? ...

?synchronized(c) {

? ? ?Iterator i = c.iterator(); // Must be in the synchronized block

? ? ?while (i.hasNext())

? ? ? ? foo(i.next());

?}

不遵从此建议将导致无法确定的行为。?

返回的 collection 不会 将 hashCode 和 equals 操作传递给底层实现 collection,但这依赖于 Object 的 equals 和 hashCode 方法。在底层实现 collection 是一个 set 或一个列表的情况下,有必要遵守这些操作的协定。

?

如果指定 collection 是可序列化的,则返回的 collection 也将是可序列化的。?

?

?

参数:

c - 被“包装”在同步 collection 中的 collection。?

返回:

指定 collection 的同步视图。

?

*/

public static <T> Collection<T> synchronizedCollection(Collection<T> c) {

return new SynchronizedCollection<T>(c);

}

?

static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {

return new SynchronizedCollection<T>(c, mutex);

}

?

/**

* @serial include

*/

static class SynchronizedCollection<E> implements Collection<E>, Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = 3053995032091335093L;

?

final Collection<E> c; // Backing Collection

final Object mutex; // Object on which to synchronize

?

SynchronizedCollection(Collection<E> c) {

if (c == null)

throw new NullPointerException();

this.c = c;

mutex = this;

}

?

SynchronizedCollection(Collection<E> c, Object mutex) {

this.c = c;

this.mutex = 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();

}

}

?

private void writeObject(ObjectOutputStream s) throws IOException {

synchronized (mutex) {

s.defaultWriteObject();

}

}

}

?

/**

返回指定 set 支持的同步(线程安全的)set。为了保证按顺序访问,必须通过返回的 set 完成对所有底层实现 set 的访问。

在返回的 set 上进行迭代时,用户必须手工在返回的 set 上进行同步:?

?

?Set s = Collections.synchronizedSet(new HashSet());

? ? ?...

?synchronized(s) {

? ? ?Iterator i = s.iterator(); // Must be in the synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

不遵从此建议将导致无法确定的行为。?

如果指定 set 是可序列化的,则返回的 set 也将是可序列化的。?

?

?

参数:

s - 被“包装”在同步 set 中的 set。?

返回:

指定 set 的同步视图。

?

*/

public static <T> Set<T> synchronizedSet(Set<T> s) {

return new SynchronizedSet<T>(s);

}

?

static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) {

return new SynchronizedSet<T>(s, mutex);

}

?

/**

* @serial include

*/

static class SynchronizedSet<E> extends SynchronizedCollection<E> implements Set<E> {

private static final long serialVersionUID = 487447009682186044L;

?

SynchronizedSet(Set<E> s) {

super(s);

}

?

SynchronizedSet(Set<E> s, Object mutex) {

super(s, mutex);

}

?

public boolean equals(Object o) {

synchronized (mutex) {

return c.equals(o);

}

}

?

public int hashCode() {

synchronized (mutex) {

return c.hashCode();

}

}

}

?

/**

返回指定有序 set 支持的同步(线程安全的)有序 set。为了保证按顺序访问,必须通过返回的有序 set(或其视图)完成对所有底层实现有序 set 的访问。

在返回的有序 set 上或者其任意 subSet、headSet 或 tailSet 视图上进行迭代时,用户必须手工在返回的有序 set 上进行同步。?

?

?SortedSet s = Collections.synchronizedSortedSet(new TreeSet());

? ? ?...

?synchronized(s) {

? ? ?Iterator i = s.iterator(); // Must be in the synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

或者:?

?SortedSet s = Collections.synchronizedSortedSet(new TreeSet());

?SortedSet s2 = s.headSet(foo);

? ? ?...

?synchronized(s) { ?// Note: s, not s2!!!

? ? ?Iterator i = s2.iterator(); // Must be in the synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

不遵从此建议将导致无法确定的行为。?

如果指定的有序 set 是可序列化的,则返回的有序 set 也将是可序列化的。?

?

?

参数:

s - 被“包装”在同步有序 set 中的有序 set。?

返回:

指定有序 set 的同步视图。

?

*/

public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) {

return new SynchronizedSortedSet<T>(s);

}

?

/**

* @serial include

*/

static class SynchronizedSortedSet<E> extends SynchronizedSet<E> implements SortedSet<E> {

private static final long serialVersionUID = 8695801310862127406L;

?

final private SortedSet<E> ss;

?

SynchronizedSortedSet(SortedSet<E> s) {

super(s);

ss = s;

}

?

SynchronizedSortedSet(SortedSet<E> s, Object mutex) {

super(s, mutex);

ss = s;

}

?

public Comparator<? super E> comparator() {

synchronized (mutex) {

return ss.comparator();

}

}

?

public SortedSet<E> subSet(E fromElement, E toElement) {

synchronized (mutex) {

return new SynchronizedSortedSet<E>(ss.subSet(fromElement, toElement), mutex);

}

}

?

public SortedSet<E> headSet(E toElement) {

synchronized (mutex) {

return new SynchronizedSortedSet<E>(ss.headSet(toElement), mutex);

}

}

?

public SortedSet<E> tailSet(E fromElement) {

synchronized (mutex) {

return new SynchronizedSortedSet<E>(ss.tailSet(fromElement), mutex);

}

}

?

public E first() {

synchronized (mutex) {

return ss.first();

}

}

?

public E last() {

synchronized (mutex) {

return ss.last();

}

}

}

?

/**

返回指定列表支持的同步(线程安全的)列表。为了保证按顺序访问,必须通过返回的列表完成所有对底层实现列表的访问。

在返回的列表上进行迭代时,用户必须手工在返回的列表上进行同步:?

?

?List list = Collections.synchronizedList(new ArrayList());

? ? ?...

?synchronized(list) {

? ? ?Iterator i = list.iterator(); // Must be in synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

不遵从此建议将导致无法确定的行为。?

如果指定列表是可序列化的,则返回的列表也将是可序列化的。?

?

?

参数:

list - 被“包装”在同步列表中的列表。?

返回:

指定列表的同步视图。

?

*/

public static <T> List<T> synchronizedList(List<T> list) {

return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<T>(list)

: new SynchronizedList<T>(list));

}

?

static <T> List<T> synchronizedList(List<T> list, Object mutex) {

return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<T>(list, mutex)

: new SynchronizedList<T>(list, mutex));

}

?

/**

* @serial include

*/

static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {

static final long serialVersionUID = -7754090372962971524L;

?

final List<E> list;

?

SynchronizedList(List<E> list) {

super(list);

this.list = list;

}

?

SynchronizedList(List<E> list, Object mutex) {

super(list, mutex);

this.list = list;

}

?

public boolean equals(Object o) {

synchronized (mutex) {

return list.equals(o);

}

}

?

public int hashCode() {

synchronized (mutex) {

return list.hashCode();

}

}

?

public E get(int index) {

synchronized (mutex) {

return list.get(index);

}

}

?

public E set(int index, E element) {

synchronized (mutex) {

return list.set(index, element);

}

}

?

public void add(int index, E element) {

synchronized (mutex) {

list.add(index, element);

}

}

?

public E remove(int index) {

synchronized (mutex) {

return list.remove(index);

}

}

?

public int indexOf(Object o) {

synchronized (mutex) {

return list.indexOf(o);

}

}

?

public int lastIndexOf(Object o) {

synchronized (mutex) {

return list.lastIndexOf(o);

}

}

?

public boolean addAll(int index, Collection<? extends E> c) {

synchronized (mutex) {

return list.addAll(index, c);

}

}

?

public ListIterator<E> listIterator() {

return list.listIterator(); // Must be manually synched by user

}

?

public ListIterator<E> listIterator(int index) {

return list.listIterator(index); // Must be manually synched by user

}

?

public List<E> subList(int fromIndex, int toIndex) {

synchronized (mutex) {

return new SynchronizedList<E>(list.subList(fromIndex, toIndex), mutex);

}

}

?

/**

* SynchronizedRandomAccessList instances are serialized as

* SynchronizedList instances to allow them to be deserialized

* in pre-1.4 JREs (which do not have SynchronizedRandomAccessList).

* This method inverts the transformation. ?As a beneficial

* side-effect, it also grafts the RandomAccess marker onto

* SynchronizedList instances that were serialized in pre-1.4 JREs.

*

* Note: Unfortunately, SynchronizedRandomAccessList instances

* serialized in 1.4.1 and deserialized in 1.4 will become

* SynchronizedList instances, as this method was missing in 1.4.

*/

private Object readResolve() {

return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<E>(list) : this);

}

}

?

/**

* @serial include

*/

static class SynchronizedRandomAccessList<E> extends SynchronizedList<E> implements RandomAccess {

?

SynchronizedRandomAccessList(List<E> list) {

super(list);

}

?

SynchronizedRandomAccessList(List<E> list, Object mutex) {

super(list, mutex);

}

?

public List<E> subList(int fromIndex, int toIndex) {

synchronized (mutex) {

return new SynchronizedRandomAccessList<E>(list.subList(fromIndex, toIndex), mutex);

}

}

?

static final long serialVersionUID = 1530674583602358482L;

?

/**

* Allows instances to be deserialized in pre-1.4 JREs (which do

* not have SynchronizedRandomAccessList). ?SynchronizedList has

* a readResolve method that inverts this transformation upon

* deserialization.

*/

private Object writeReplace() {

return new SynchronizedList<E>(list);

}

}

?

/**

返回由指定映射支持的同步(线程安全的)映射。为了保证按顺序访问,必须通过返回的映射完成所有对底层实现映射的访问。

在返回映射的任意 collection 视图上进行迭代时,用户必须手工在返回的映射上进行同步:?

?

?Map m = Collections.synchronizedMap(new HashMap());

? ? ?...

?Set s = m.keySet(); ?// Needn't be in synchronized block

? ? ?...

?synchronized(m) { ?// Synchronizing on m, not s!

? ? ?Iterator i = s.iterator(); // Must be in synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

不遵从此建议将导致无法确定的行为。?

如果指定映射是可序列化的,则返回的映射也将是可序列化的。?

?

?

参数:

m - 被“包装”在同步映射中的映射。?

返回:

指定映射的同步视图。

?

*/

public static <K, V> Map<K, V> synchronizedMap(Map<K, V> m) {

return new SynchronizedMap<K, V>(m);

}

?

/**

* @serial include

*/

private static class SynchronizedMap<K, V> implements Map<K, V>, Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = 1978198479659022715L;

?

private final Map<K, V> m; // Backing Map

final Object mutex; // Object on which to synchronize

?

SynchronizedMap(Map<K, V> m) {

if (m == null)

throw new NullPointerException();

this.m = m;

mutex = this;

}

?

SynchronizedMap(Map<K, V> m, Object mutex) {

this.m = m;

this.mutex = mutex;

}

?

public int size() {

synchronized (mutex) {

return m.size();

}

}

?

public boolean isEmpty() {

synchronized (mutex) {

return m.isEmpty();

}

}

?

public boolean containsKey(Object key) {

synchronized (mutex) {

return m.containsKey(key);

}

}

?

public boolean containsValue(Object value) {

synchronized (mutex) {

return m.containsValue(value);

}

}

?

public V get(Object key) {

synchronized (mutex) {

return m.get(key);

}

}

?

public V put(K key, V value) {

synchronized (mutex) {

return m.put(key, value);

}

}

?

public V remove(Object key) {

synchronized (mutex) {

return m.remove(key);

}

}

?

public void putAll(Map<? extends K, ? extends V> map) {

synchronized (mutex) {

m.putAll(map);

}

}

?

public void clear() {

synchronized (mutex) {

m.clear();

}

}

?

private transient Set<K> keySet = null;

private transient Set<Map.Entry<K, V>> entrySet = null;

private transient Collection<V> values = null;

?

public Set<K> keySet() {

synchronized (mutex) {

if (keySet == null)

keySet = new SynchronizedSet<K>(m.keySet(), mutex);

return keySet;

}

}

?

public Set<Map.Entry<K, V>> entrySet() {

synchronized (mutex) {

if (entrySet == null)

entrySet = new SynchronizedSet<Map.Entry<K, V>>(m.entrySet(), mutex);

return entrySet;

}

}

?

public Collection<V> values() {

synchronized (mutex) {

if (values == null)

values = new SynchronizedCollection<V>(m.values(), mutex);

return values;

}

}

?

public boolean equals(Object o) {

synchronized (mutex) {

return m.equals(o);

}

}

?

public int hashCode() {

synchronized (mutex) {

return m.hashCode();

}

}

?

public String toString() {

synchronized (mutex) {

return m.toString();

}

}

?

private void writeObject(ObjectOutputStream s) throws IOException {

synchronized (mutex) {

s.defaultWriteObject();

}

}

}

?

/**

返回指定有序映射支持的同步(线程安全的)有序映射。为了保证按顺序访问,必须通过返回的有序映射(或其视图)完成对所有底层有序映射的访问。

当在返回的有序映射的 collection 视图或者其任何 subMap、headMap 或 tailMap 视图进行迭代时,用户必须手工在该映射上进行同步:?

?

?SortedMap m = Collections.synchronizedSortedMap(new TreeMap());

? ? ?...

?Set s = m.keySet(); ?// Needn't be in synchronized block

? ? ?...

?synchronized(m) { ?// Synchronizing on m, not s!

? ? ?Iterator i = s.iterator(); // Must be in synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

或者:?

?SortedMap m = Collections.synchronizedSortedMap(new TreeMap());

?SortedMap m2 = m.subMap(foo, bar);

? ? ?...

?Set s2 = m2.keySet(); ?// Needn't be in synchronized block

? ? ?...

?synchronized(m) { ?// Synchronizing on m, not m2 or s2!

? ? ?Iterator i = s.iterator(); // Must be in synchronized block

? ? ?while (i.hasNext())

? ? ? ? ?foo(i.next());

?}

不遵从此建议将导致无法确定的行为。?

如果指定的有序映射是可序列化的,则返回的有序映射也将是可序列化的。?

?

?

参数:

m - 被“包装”在同步有序映射中的有序映射。?

返回:

指定有序映射的同步视图。

*/

public static <K, V> SortedMap<K, V> synchronizedSortedMap(SortedMap<K, V> m) {

return new SynchronizedSortedMap<K, V>(m);

}

?

/**

* @serial include

*/

static class SynchronizedSortedMap<K, V> extends SynchronizedMap<K, V> implements SortedMap<K, V> {

private static final long serialVersionUID = -8798146769416483793L;

?

private final SortedMap<K, V> sm;

?

SynchronizedSortedMap(SortedMap<K, V> m) {

super(m);

sm = m;

}

?

SynchronizedSortedMap(SortedMap<K, V> m, Object mutex) {

super(m, mutex);

sm = m;

}

?

public Comparator<? super K> comparator() {

synchronized (mutex) {

return sm.comparator();

}

}

?

public SortedMap<K, V> subMap(K fromKey, K toKey) {

synchronized (mutex) {

return new SynchronizedSortedMap<K, V>(sm.subMap(fromKey, toKey), mutex);

}

}

?

public SortedMap<K, V> headMap(K toKey) {

synchronized (mutex) {

return new SynchronizedSortedMap<K, V>(sm.headMap(toKey), mutex);

}

}

?

public SortedMap<K, V> tailMap(K fromKey) {

synchronized (mutex) {

return new SynchronizedSortedMap<K, V>(sm.tailMap(fromKey), mutex);

}

}

?

public K firstKey() {

synchronized (mutex) {

return sm.firstKey();

}

}

?

public K lastKey() {

synchronized (mutex) {

return sm.lastKey();

}

}

}

?

// Dynamically typesafe collection wrappers

?

/**

返回指定 collection 的一个动态类型安全视图。试图插入一个错误类型的元素将导致立即抛出 ClassCastException。假设在生成动态类型安全视图之前,collection 不包含任何类型不正确的元素,并且所有对该 collection 的后续访问都通过该视图进行,则可以保证 该 collection 不包含类型不正确的元素。?

一般的编程语言机制中都提供了编译时(静态)类型检查,但是一些未经检查的强制转换可能会使此机制无效。通常这不是一个问题,因为编译器会在所有这类未经检查的操作上发出警告。但有的时候,只进行单独的静态类型检查并不够。例如,假设将 collection 传递给一个第三方库,则库代码不能通过插入一个错误类型的元素来毁坏 collection。?

?

动态类型安全视图的另一个用途是调试。假设某个程序运行失败并抛出 ClassCastException,这指示一个类型不正确的元素被放入已参数化 collection 中。不幸的是,该异常可以发生在插入错误元素之后的任何时间,因此,这通常只能提供很少或无法提供任何关于问题真正来源的信息。如果问题是可再现的,那么可以暂时修改程序,使用一个动态类型安全视图来包装该 collection,通过这种方式可快速确定问题的来源。例如,以下声明:?

?

? ? Collection<String> c = new HashSet<String>();

可以暂时用下面的声明代替:?

? ? Collection<String> c = Collections.checkedCollection(

? ? ? ? new HashSet<String>(), String.class);

再次运行程序会造成它在将类型不正确的元素插入 collection 的地方失败,从而清楚地识别问题的来源。问题得以解决后,可以将修改后的声明转换回原来的声明。?

返回的 collection 不会 将 hashCode 和 equals 操作传递给底层实现 collection,但这依赖于 Object 的 equals 和 hashCode 方法。在底层实现 collection 是一个 set 或一个列表的情况下,有必要遵守这些操作的协定。?

?

如果指定 collection 是可序列化的,则返回的 collection 也将是可序列化的。?

?

?

参数:

c - 将返回其动态类型安全视图的 collection

type - 允许 c 持有的元素类型?

返回:

指定 collection 的动态安全类型视图

从以下版本开始:?

1.5?

?

*/

public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type) {

return new CheckedCollection<E>(c, type);

}

?

/**

* @serial include

*/

static class CheckedCollection<E> implements Collection<E>, Serializable {

private static final long serialVersionUID = 1578914078182001775L;

?

final Collection<E> c;

final Class<E> type;

?

void typeCheck(Object o) {

if (!type.isInstance(o))

throw new ClassCastException("Attempt to insert " + o.getClass()

+ " element into collection with element type " + type);

}

?

CheckedCollection(Collection<E> c, Class<E> type) {

if (c == null || type == null)

throw new NullPointerException();

this.c = c;

this.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 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 void clear() {

c.clear();

}

?

public Iterator<E> iterator() {

return new Iterator<E>() {

private final Iterator<E> it = c.iterator();

?

public boolean hasNext() {

return it.hasNext();

}

?

public E next() {

return it.next();

}

?

public void remove() {

it.remove();

}

};

}

?

public boolean add(E e) {

typeCheck(e);

return c.add(e);

}

?

public boolean addAll(Collection<? extends E> coll) {

/*

* Dump coll into an array of the required type. ?This serves

* three purposes: it insulates us from concurrent changes in

* the contents of coll, it type-checks all of the elements in

* coll, and it provides all-or-nothing semantics (which we

* wouldn't get if we type-checked each element as we added it).

*/

E[] a = null;

try {

a = coll.toArray(zeroLengthElementArray());

} catch (ArrayStoreException e) {

throw new ClassCastException();

}

?

boolean result = false;

for (E e : a)

result |= c.add(e);

return result;

}

?

private E[] zeroLengthElementArray = null; // Lazily initialized

?

/*

* We don't need locking or volatile, because it's OK if we create

* several zeroLengthElementArrays, and they're immutable.

*/

E[] zeroLengthElementArray() {

if (zeroLengthElementArray == null)

zeroLengthElementArray = (E[]) Array.newInstance(type, 0);

return zeroLengthElementArray;

}

}

?

/**

返回指定 set 的一个动态类型安全视图。试图插入一个错误类型的元素将导致立即抛出 ClassCastException。假设在生成动态类型安全视图之前,set 不包含任何类型不正确的元素,并且所有对该 set 的后续访问都通过该视图进行,则可以保证 该 set 不包含类型不正确的元素。?

可以在 checkedCollection 方法的文档中找到有关使用动态类型安全视图的讨论。?

?

如果指定 set 是可序列化的,则返回的 set 也将是可序列化的。?

?

?

参数:

s - 将返回其动态类型安全视图的 set

type - 允许 s 持有的元素类型?

返回:

指定 set 的动态安全类型视图

从以下版本开始:?

1.5?

?

*/

public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {

return new CheckedSet<E>(s, type);

}

?

/**

* @serial include

*/

static class CheckedSet<E> extends CheckedCollection<E> implements Set<E>, Serializable {

private static final long serialVersionUID = 4694047833775013803L;

?

CheckedSet(Set<E> s, Class<E> elementType) {

super(s, elementType);

}

?

public boolean equals(Object o) {

return o == this || c.equals(o);

}

?

public int hashCode() {

return c.hashCode();

}

}

?

/**

返回指定有序 set 的一个动态类型安全视图。试图插入一个错误类型的元素将导致立即抛出 ClassCastException。假设在生成动态类型安全视图之前,有序 set 不包含任何类型不正确的元素,并且所有对该有序 set 的后续访问都通过该视图进行,则可以保证 该有序 set 不包含类型不正确的元素。?

可以在 checkedCollection 方法的文档中找到有关使用动态类型安全视图的讨论。?

?

如果指定的有序 set 是可序列化的,则返回的有序 set 也将是可序列化的。?

?

?

参数:

s - 将返回其动态类型安全视图的 set

type - 允许 s 持有的元素类型?

返回:

指定有序 set 的动态安全类型视图

从以下版本开始:?

1.5?

?

*/

public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, Class<E> type) {

return new CheckedSortedSet<E>(s, type);

}

?

/**

* @serial include

*/

static class CheckedSortedSet<E> extends CheckedSet<E> implements SortedSet<E>, Serializable {

private static final long serialVersionUID = 1599911165492914959L;

private final SortedSet<E> ss;

?

CheckedSortedSet(SortedSet<E> s, Class<E> type) {

super(s, type);

ss = s;

}

?

public Comparator<? super E> comparator() {

return ss.comparator();

}

?

public E first() {

return ss.first();

}

?

public E last() {

return ss.last();

}

?

public SortedSet<E> subSet(E fromElement, E toElement) {

return new CheckedSortedSet<E>(ss.subSet(fromElement, toElement), type);

}

?

public SortedSet<E> headSet(E toElement) {

return new CheckedSortedSet<E>(ss.headSet(toElement), type);

}

?

public SortedSet<E> tailSet(E fromElement) {

return new CheckedSortedSet<E>(ss.tailSet(fromElement), type);

}

}

?

/**

返回指定列表的一个动态类型安全视图。试图插入一个错误类型的元素将导致立即抛出 ClassCastException。假设在生成动态类型安全视图之前,列表不包含任何类型不正确的元素,并且所有对该列表的后续访问都通过该视图进行,则可以保证 此列表不包含类型不正确的元素。?

可以在 checkedCollection 方法的文档中找到有关使用动态类型安全视图的讨论。?

?

如果指定列表是可序列化的,则返回的列表也将是可序列化的。?

?

?

参数:

list - 将返回其动态类型安全视图的列表

type - 允许 list 持有的元素类型?

返回:

指定列表的一个动态安全类型视图

从以下版本开始:?

1.5?

?

*/

public static <E> List<E> checkedList(List<E> list, Class<E> type) {

return (list instanceof RandomAccess ? new CheckedRandomAccessList<E>(list, type) : new CheckedList<E>(list,

type));

}

?

/**

* @serial include

*/

static class CheckedList<E> extends CheckedCollection<E> implements List<E> {

static final long serialVersionUID = 65247728283967356L;

final List<E> list;

?

CheckedList(List<E> list, Class<E> type) {

super(list, type);

this.list = list;

}

?

public boolean equals(Object o) {

return o == this || list.equals(o);

}

?

public int hashCode() {

return list.hashCode();

}

?

public E get(int index) {

return list.get(index);

}

?

public E remove(int index) {

return list.remove(index);

}

?

public int indexOf(Object o) {

return list.indexOf(o);

}

?

public int lastIndexOf(Object o) {

return list.lastIndexOf(o);

}

?

public E set(int index, E element) {

typeCheck(element);

return list.set(index, element);

}

?

public void add(int index, E element) {

typeCheck(element);

list.add(index, element);

}

?

public boolean addAll(int index, Collection<? extends E> c) {

// See CheckCollection.addAll, above, for an explanation

E[] a = null;

try {

a = c.toArray(zeroLengthElementArray());

} catch (ArrayStoreException e) {

throw new ClassCastException();

}

?

return list.addAll(index, Arrays.asList(a));

}

?

public ListIterator<E> listIterator() {

return listIterator(0);

}

?

public ListIterator<E> listIterator(final int index) {

return new ListIterator<E>() {

ListIterator<E> i = list.listIterator(index);

?

public boolean hasNext() {

return i.hasNext();

}

?

public E next() {

return i.next();

}

?

public boolean hasPrevious() {

return i.hasPrevious();

}

?

public E previous() {

return i.previous();

}

?

public int nextIndex() {

return i.nextIndex();

}

?

public int previousIndex() {

return i.previousIndex();

}

?

public void remove() {

i.remove();

}

?

public void set(E e) {

typeCheck(e);

i.set(e);

}

?

public void add(E e) {

typeCheck(e);

i.add(e);

}

};

}

?

public List<E> subList(int fromIndex, int toIndex) {

return new CheckedList<E>(list.subList(fromIndex, toIndex), type);

}

}

?

/**

* @serial include

*/

static class CheckedRandomAccessList<E> extends CheckedList<E> implements RandomAccess {

private static final long serialVersionUID = 1638200125423088369L;

?

CheckedRandomAccessList(List<E> list, Class<E> type) {

super(list, type);

}

?

public List<E> subList(int fromIndex, int toIndex) {

return new CheckedRandomAccessList<E>(list.subList(fromIndex, toIndex), type);

}

}

?

/**

返回指定映射的一个动态类型安全视图。试图插入一个具有错误类型键或值的映射关系将导致立即抛出 ClassCastException。类似地,试图修改当前与键关联的值(无论是直接通过映射自身,还是通过一个从该映射项集视图中获得的 Map.Entry 实例)都将导致立即抛出 ClassCastException。?

假设在生成动态类型安全视图之前,映射中不包含任何类型不正确的键或值,并且所有对映射的后续访问都通过该视图(或其 collection 视图之一)进行,则可以保证 该映射不包含类型不正确的键或值。?

?

可以在 checkedCollection 方法的文档中找到有关使用动态类型安全视图的讨论。?

?

如果指定映射是可序列化的,则返回的映射也将是可序列化的。?

?

?

参数:

m - 将返回其动态类型安全视图的映射

keyType - 允许 m 持有的键类型

valueType - 允许 m 持有的值类型?

返回:

指定映射的动态类型安全视图

从以下版本开始:?

1.5?

?

*/

public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {

return new CheckedMap<K, V>(m, keyType, valueType);

}

?

/**

* @serial include

*/

private static class CheckedMap<K, V> implements Map<K, V>, Serializable {

private static final long serialVersionUID = 5742860141034234728L;

?

private final Map<K, V> m;

final Class<K> keyType;

final Class<V> valueType;

?

private void typeCheck(Object key, Object value) {

if (!keyType.isInstance(key))

throw new ClassCastException("Attempt to insert " + key.getClass()

+ " key into collection with key type " + keyType);

?

if (!valueType.isInstance(value))

throw new ClassCastException("Attempt to insert " + value.getClass()

+ " value into collection with value type " + valueType);

}

?

CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {

if (m == null || keyType == null || valueType == null)

throw new NullPointerException();

this.m = m;

this.keyType = keyType;

this.valueType = valueType;

}

?

public int size() {

return m.size();

}

?

public boolean isEmpty() {

return m.isEmpty();

}

?

public boolean containsKey(Object key) {

return m.containsKey(key);

}

?

public boolean containsValue(Object v) {

return m.containsValue(v);

}

?

public V get(Object key) {

return m.get(key);

}

?

public V remove(Object key) {

return m.remove(key);

}

?

public void clear() {

m.clear();

}

?

public Set<K> keySet() {

return m.keySet();

}

?

public Collection<V> values() {

return m.values();

}

?

public boolean equals(Object o) {

return o == this || m.equals(o);

}

?

public int hashCode() {

return m.hashCode();

}

?

public String toString() {

return m.toString();

}

?

public V put(K key, V value) {

typeCheck(key, value);

return m.put(key, value);

}

?

public void putAll(Map<? extends K, ? extends V> t) {

// See CheckCollection.addAll, above, for an explanation

K[] keys = null;

try {

keys = t.keySet().toArray(zeroLengthKeyArray());

} catch (ArrayStoreException e) {

throw new ClassCastException();

}

V[] values = null;

try {

values = t.values().toArray(zeroLengthValueArray());

} catch (ArrayStoreException e) {

throw new ClassCastException();

}

?

if (keys.length != values.length)

throw new ConcurrentModificationException();

?

for (int i = 0; i < keys.length; i++)

m.put(keys[i], values[i]);

}

?

// Lazily initialized

private K[] zeroLengthKeyArray = null;

private V[] zeroLengthValueArray = null;

?

/*

* We don't need locking or volatile, because it's OK if we create

* several zeroLengthValueArrays, and they're immutable.

*/

private K[] zeroLengthKeyArray() {

if (zeroLengthKeyArray == null)

zeroLengthKeyArray = (K[]) Array.newInstance(keyType, 0);

return zeroLengthKeyArray;

}

?

private V[] zeroLengthValueArray() {

if (zeroLengthValueArray == null)

zeroLengthValueArray = (V[]) Array.newInstance(valueType, 0);

return zeroLengthValueArray;

}

?

private transient Set<Map.Entry<K, V>> entrySet = null;

?

public Set<Map.Entry<K, V>> entrySet() {

if (entrySet == null)

entrySet = new CheckedEntrySet<K, V>(m.entrySet(), valueType);

return entrySet;

}

?

/**

* We need this class in addition to CheckedSet as Map.Entry permits

* modification of the backing Map via the setValue operation. ?This

* class is subtle: there are many possible attacks that must be

* thwarted.

*

* @serial exclude

*/

static class CheckedEntrySet<K, V> implements Set<Map.Entry<K, V>> {

Set<Map.Entry<K, V>> s;

Class<V> valueType;

?

CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) {

this.s = s;

this.valueType = valueType;

}

?

public int size() {

return s.size();

}

?

public boolean isEmpty() {

return s.isEmpty();

}

?

public String toString() {

return s.toString();

}

?

public int hashCode() {

return s.hashCode();

}

?

public boolean remove(Object o) {

return s.remove(o);

}

?

public boolean removeAll(Collection<?> coll) {

return s.removeAll(coll);

}

?

public boolean retainAll(Collection<?> coll) {

return s.retainAll(coll);

}

?

public void clear() {

s.clear();

}

?

public boolean add(Map.Entry<K, V> e) {

throw new UnsupportedOperationException();

}

?

public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) {

throw new UnsupportedOperationException();

}

?

public Iterator<Map.Entry<K, V>> iterator() {

return new Iterator<Map.Entry<K, V>>() {

Iterator<Map.Entry<K, V>> i = s.iterator();

?

public boolean hasNext() {

return i.hasNext();

}

?

public void remove() {

i.remove();

}

?

public Map.Entry<K, V> next() {

return new CheckedEntry<K, V>(i.next(), valueType);

}

};

}

?

public Object[] toArray() {

Object[] source = s.toArray();

?

/*

* Ensure that we don't get an ArrayStoreException even if

* s.toArray returns an array of something other than Object

*/

Object[] dest = (CheckedEntry.class.isInstance(source.getClass().getComponentType()) ? source

: new Object[source.length]);

?

for (int i = 0; i < source.length; i++)

dest[i] = new CheckedEntry<K, V>((Map.Entry<K, V>) source[i], valueType);

return dest;

}

?

public <T> T[] toArray(T[] a) {

// We don't pass a to s.toArray, to avoid window of

// vulnerability wherein an unscrupulous multithreaded client

// could get his hands on raw (unwrapped) Entries from s.

Object[] arr = s.toArray(a.length == 0 ? a : Arrays.copyOf(a, 0));

?

for (int i = 0; i < arr.length; i++)

arr[i] = new CheckedEntry<K, V>((Map.Entry<K, V>) arr[i], valueType);

if (arr.length > a.length)

return (T[]) arr;

?

System.arraycopy(arr, 0, a, 0, arr.length);

if (a.length > arr.length)

a[arr.length] = null;

return a;

}

?

/**

* This method is overridden to protect the backing set against

* an object with a nefarious equals function that senses

* that the equality-candidate is Map.Entry and calls its

* setValue method.

*/

public boolean contains(Object o) {

if (!(o instanceof Map.Entry))

return false;

return s.contains(new CheckedEntry<K, V>((Map.Entry<K, V>) o, valueType));

}

?

/**

* The next two methods are overridden to protect against

* an unscrupulous collection whose contains(Object o) method

* senses when o is a Map.Entry, and calls o.setValue.

*/

public boolean containsAll(Collection<?> coll) {

Iterator<?> e = coll.iterator();

while (e.hasNext())

if (!contains(e.next())) // Invokes safe contains() above

return false;

return true;

}

?

public boolean equals(Object o) {

if (o == this)

return true;

if (!(o instanceof Set))

return false;

Set<?> that = (Set<?>) o;

if (that.size() != s.size())

return false;

return containsAll(that); // Invokes safe containsAll() above

}

?

/**

* This "wrapper class" serves two purposes: it prevents

* the client from modifying the backing Map, by short-circuiting

* the setValue method, and it protects the backing Map against

* an ill-behaved Map.Entry that attempts to modify another

* Map Entry when asked to perform an equality check.

*/

private static class CheckedEntry<K, V> implements Map.Entry<K, V> {

private Map.Entry<K, V> e;

private Class<V> valueType;

?

CheckedEntry(Map.Entry<K, V> e, Class<V> valueType) {

this.e = e;

this.valueType = valueType;

}

?

public K getKey() {

return e.getKey();

}

?

public V getValue() {

return e.getValue();

}

?

public int hashCode() {

return e.hashCode();

}

?

public String toString() {

return e.toString();

}

?

public V setValue(V value) {

if (!valueType.isInstance(value))

throw new ClassCastException("Attempt to insert " + value.getClass()

+ " value into collection with value type " + valueType);

return e.setValue(value);

}

?

public boolean equals(Object o) {

if (!(o instanceof Map.Entry))

return false;

Map.Entry t = (Map.Entry) o;

return eq(e.getKey(), t.getKey()) && eq(e.getValue(), t.getValue());

}

}

}

}

?

/**

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Class<V> valueType)返回指定有序映射的一个动态类型安全视图。试图插入一个具有错误类型键或值的映射关系将导致立即抛出 ClassCastException。类似地,试图修改当前与键关联的值(无论是直接通过映射自身,还是通过一个从该映射项集视图中获得的 Map.Entry 实例)将导致立即抛出 ClassCastException。?

假设在生成动态类型安全视图之前,映射中不包含任何类型不正确的键或值,并且所有对映射的后续访问都通过该视图(或其 collection 视图之一)进行,则可以保证 此映射不包含类型不正确的键或值。?

?

可以在 checkedCollection 方法的文档中找到有关使用动态类型安全视图的讨论。?

?

如果指定映射是可序列化的,则返回的映射也将是可序列化的。?

?

?

参数:

m - 将返回其动态类型安全视图的映射

keyType - 允许 m 持有的键的类型

valueType - 允许 m 持有的值的类型?

返回:

指定映射的动态类型安全视图

从以下版本开始:?

1.5?

?

*/

public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m, Class<K> keyType, Class<V> valueType) {

return new CheckedSortedMap<K, V>(m, keyType, valueType);

}

?

/**

* @serial include

*/

static class CheckedSortedMap<K, V> extends CheckedMap<K, V> implements SortedMap<K, V>, Serializable {

private static final long serialVersionUID = 1599671320688067438L;

?

private final SortedMap<K, V> sm;

?

CheckedSortedMap(SortedMap<K, V> m, Class<K> keyType, Class<V> valueType) {

super(m, keyType, valueType);

sm = m;

}

?

public Comparator<? super K> comparator() {

return sm.comparator();

}

?

public K firstKey() {

return sm.firstKey();

}

?

public K lastKey() {

return sm.lastKey();

}

?

public SortedMap<K, V> subMap(K fromKey, K toKey) {

return new CheckedSortedMap<K, V>(sm.subMap(fromKey, toKey), keyType, valueType);

}

?

public SortedMap<K, V> headMap(K toKey) {

return new CheckedSortedMap<K, V>(sm.headMap(toKey), keyType, valueType);

}

?

public SortedMap<K, V> tailMap(K fromKey) {

return new CheckedSortedMap<K, V>(sm.tailMap(fromKey), keyType, valueType);

}

}

?

// Miscellaneous

?

/**

空的 set(不可变的)。此 set 是可序列化的。?

?

另请参见:

emptySet()

?

*/

public static final Set EMPTY_SET = new EmptySet();

?

/**

返回空的 set(不可变的)。此 set 是可序列化的。与 like-named 字段不同,此方法是参数化的。?

以下示例演示了获得空 set 的类型安全 (type-safe) 方式:?

?

? ? Set<String> s = Collections.emptySet();

实现注意事项:实现此方法不需要为每次调用创建一个单独的 Set 对象。使用此方法的开销与使用 like-named 字段相当。(与此方法不同,该字段不提供类型安全。)?

?

从以下版本开始:?

1.5?

另请参见:

EMPTY_SET

?

*/

public static final <T> Set<T> emptySet() {

return (Set<T>) EMPTY_SET;

}

?

/**

* @serial include

*/

private static class EmptySet extends AbstractSet<Object> implements Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = 1582296315990362920L;

?

public Iterator<Object> iterator() {

return new Iterator<Object>() {

public boolean hasNext() {

return false;

}

?

public Object next() {

throw new NoSuchElementException();

}

?

public void remove() {

throw new UnsupportedOperationException();

}

};

}

?

public int size() {

return 0;

}

?

public boolean contains(Object obj) {

return false;

}

?

// Preserves singleton property

private Object readResolve() {

return EMPTY_SET;

}

}

?

/**

空的列表(不可变的)。此列表是可序列化的。?

?

另请参见:

emptyList()

?

*/

public static final List EMPTY_LIST = new EmptyList();

?

/**

返回空的列表(不可变的)。此列表是可序列化的。?

以下示例演示了获得空列表的类型安全方式:?

?

? ? List<String> s = Collections.emptyList();

实现注意事项:实现此方法不需要为每次调用创建一个单独的 List 对象。使用此方法的开销与使用 like-named 字段相当。(与此方法不同,该字段不提供类型安全。)?

?

从以下版本开始:?

1.5?

另请参见:

EMPTY_LIST

?

*/

public static final <T> List<T> emptyList() {

return (List<T>) EMPTY_LIST;

}

?

/**

* @serial include

*/

private static class EmptyList extends AbstractList<Object> implements RandomAccess, Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = 8842843931221139166L;

?

public int size() {

return 0;

}

?

public boolean contains(Object obj) {

return false;

}

?

public Object get(int index) {

throw new IndexOutOfBoundsException("Index: " + index);

}

?

// Preserves singleton property

private Object readResolve() {

return EMPTY_LIST;

}

}

?

/**

空的映射(不可变的)。此映射是可序列化的。?

?

从以下版本开始:?

1.3?

另请参见:

emptyMap()

?

*/

public static final Map EMPTY_MAP = new EmptyMap();

?

/**

返回空的映射(不可变的)。此映射是可序列化的。?

以下示例演示了获得空 set 的类型安全方式:?

?

? ? Map<String, Date> s = Collections.emptyMap();

实现注意事项:实现此方法不需要为每次调用创建一个单独的 Map 对象。使用此方法的开销与使用 like-named 字段相当。(与此方法不同,该字段不提供类型安全。)?

?

从以下版本开始:?

1.5?

另请参见:

EMPTY_MAP

?

*/

public static final <K, V> Map<K, V> emptyMap() {

return (Map<K, V>) EMPTY_MAP;

}

?

private static class EmptyMap extends AbstractMap<Object, Object> implements Serializable {

?

private static final long serialVersionUID = 6428348081105594320L;

?

public int size() {

return 0;

}

?

public boolean isEmpty() {

return true;

}

?

public boolean containsKey(Object key) {

return false;

}

?

public boolean containsValue(Object value) {

return false;

}

?

public Object get(Object key) {

return null;

}

?

public Set<Object> keySet() {

return Collections.<Object> emptySet();

}

?

public Collection<Object> values() {

return Collections.<Object> emptySet();

}

?

public Set<Map.Entry<Object, Object>> entrySet() {

return Collections.emptySet();

}

?

public boolean equals(Object o) {

return (o instanceof Map) && ((Map) o).size() == 0;

}

?

public int hashCode() {

return 0;

}

?

// Preserves singleton property

private Object readResolve() {

return EMPTY_MAP;

}

}

?

/**

返回一个只包含指定对象的不可变列表。返回的列表是可序列化的。?

?

参数:

o - 将存储到返回列表中的单独对象。?

返回:

一个只包含指定对象的不可变列表。

从以下版本开始:?

1.3?

?

*/

public static <T> Set<T> singleton(T o) {

return new SingletonSet<T>(o);

}

?

/**

* @serial include

*/

private static class SingletonSet<E> extends AbstractSet<E> implements Serializable {

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = 3193687207550431679L;

?

final private E element;

?

SingletonSet(E e) {

element = e;

}

?

public Iterator<E> iterator() {

return new Iterator<E>() {

private boolean hasNext = true;

?

public boolean hasNext() {

return hasNext;

}

?

public E next() {

if (hasNext) {

hasNext = false;

return element;

}

throw new NoSuchElementException();

}

?

public void remove() {

throw new UnsupportedOperationException();

}

};

}

?

public int size() {

return 1;

}

?

public boolean contains(Object o) {

return eq(o, element);

}

}

?

/**

返回一个不可变的映射,它只将指定键映射到指定值。返回的映射是可序列化的。?

?

参数:

key - 将存储到返回映射中的单独键。

value - 返回的映射将 key 映射到的值。?

返回:

只包含指定键-值映射关系的不可变映射。

从以下版本开始:?

1.3?

?

*/

public static <T> List<T> singletonList(T o) {

return new SingletonList<T>(o);

}

?

private static class SingletonList<E> extends AbstractList<E> implements RandomAccess, Serializable {

?

static final long serialVersionUID = 3093736618740652951L;

?

private final E element;

?

SingletonList(E obj) {

element = obj;

}

?

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;

}

}

?

/**

返回一个不可变的映射,它只将指定键映射到指定值。返回的映射是可序列化的。?

?

参数:

key - 将存储到返回映射中的单独键。

value - 返回的映射将 key 映射到的值。?

返回:

只包含指定键-值映射关系的不可变映射。

从以下版本开始:?

1.3?

?

*/

public static <K, V> Map<K, V> singletonMap(K key, V value) {

return new SingletonMap<K, V>(key, value);

}

?

private static class SingletonMap<K, V> extends AbstractMap<K, V> implements Serializable {

private static final long serialVersionUID = -6979724477215052911L;

?

private final K k;

private final V v;

?

SingletonMap(K key, V value) {

k = key;

v = value;

}

?

public int size() {

return 1;

}

?

public boolean isEmpty() {

return false;

}

?

public boolean containsKey(Object key) {

return eq(key, k);

}

?

public boolean containsValue(Object value) {

return eq(value, v);

}

?

public V get(Object key) {

return (eq(key, k) ? v : null);

}

?

private transient Set<K> keySet = null;

private transient Set<Map.Entry<K, V>> entrySet = null;

private transient Collection<V> values = null;

?

public Set<K> keySet() {

if (keySet == null)

keySet = singleton(k);

return keySet;

}

?

public Set<Map.Entry<K, V>> entrySet() {

if (entrySet == null)

entrySet = Collections.<Map.Entry<K, V>> singleton(new SimpleImmutableEntry<K, V>(k, v));

return entrySet;

}

?

public Collection<V> values() {

if (values == null)

values = singleton(v);

return values;

}

?

}

?

/**

返回由指定对象的 n 个副本组成的不可变列表。新分配的数据对象非常小(它只包含一个对该数据对象的引用)。在通过与 List.addAll 方法组合来增大列表时,此方法很有用。返回的列表是可序列化的。?

?

参数:

n - 返回列表中的元素数。

o - 重复出现在返回列表中的元素。?

返回:

由指定对象 n 个副本组成的不可变列表。?

抛出:?

IllegalArgumentException - 如果 n < 0。

另请参见:

List.addAll(Collection), List.addAll(int, Collection)

?

*/

public static <T> List<T> nCopies(int n, T o) {

if (n < 0)

throw new IllegalArgumentException("List length = " + n);

return new CopiesList<T>(n, o);

}

?

/**

* @serial include

*/

private static class CopiesList<E> extends AbstractList<E> implements RandomAccess, Serializable {

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;

}

?

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);

}

}

?

/**

返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。(自然顺序是通过对象自身的 compareTo 方法强行排序的。)此方法允许使用单个语句,以逆自然顺序对实现了 Comparable 接口的对象 collection(或数组)进行排序(或维护)。例如,假设 a 是一个字符串数组。那么:

? ? ? ? ? ? ? ?Arrays.sort(a, Collections.reverseOrder());

将按照逆字典(字母)顺序对数组进行排序。

返回的比较器是可序列化的。?

?

?

返回:

返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。

另请参见:

Comparable

?

*/

public static <T> Comparator<T> reverseOrder() {

return (Comparator<T>) REVERSE_ORDER;

}

?

private static final Comparator REVERSE_ORDER = new ReverseComparator();

?

/**

* @serial include

*/

private static class ReverseComparator<T> implements Comparator<Comparable<Object>>, Serializable {

?

// use serialVersionUID from JDK 1.2.2 for interoperability

private static final long serialVersionUID = 7207038068494060240L;

?

public int compare(Comparable<Object> c1, Comparable<Object> c2) {

return c2.compareTo(c1);

}

?

private Object readResolve() {

return reverseOrder();

}

}

?

/**

返回一个比较器,它强行逆转指定比较器的顺序。如果指定比较器为 null,则此方法等同于 reverseOrder()(换句话说,它返回一个比较器,该比较器将强行逆转实现了 Comparable 接口的对象 collection 的自然顺序)。?

返回的比较器是可序列化的(假设指定的比较器也是可序列化的或者为 null)。?

?

?

返回:

强行逆转指定比较器顺序的比较器。

从以下版本开始:?

1.5?

?

*/

public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {

if (cmp == null)

return reverseOrder();

?

return new ReverseComparator2<T>(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

*/

private 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);

}

}

?

/**

返回一个指定 collection 上的枚举。此方法提供与遗留 API 的互操作性,遗留 API 需要一个枚举作为输入。?

?

参数:

c - 将返回其枚举的 collection。?

返回:

指定 collection 上的一个枚举。

另请参见:

Enumeration

?

*/

public static <T> Enumeration<T> enumeration(final Collection<T> c) {

return new Enumeration<T>() {

Iterator<T> i = c.iterator();

?

public boolean hasMoreElements() {

return i.hasNext();

}

?

public T nextElement() {

return i.next();

}

};

}

?

/**

返回一个数组列表,它按返回顺序包含指定枚举返回的元素。此方法提供返回枚举的遗留 API 与需要 collection 的新 API 之间的互操作性。?

?

参数:

e - 为返回的数组列表提供元素的枚举?

返回:

包含指定枚举返回元素的数组列表。

从以下版本开始:?

1.4?

另请参见:

Enumeration, ArrayList

?

*/

public static <T> ArrayList<T> list(Enumeration<T> e) {

ArrayList<T> l = new ArrayList<T>();

while (e.hasMoreElements())

l.add(e.nextElement());

return l;

}

?

/**

* Returns true if the specified arguments are equal, or both null.

*/

private static boolean eq(Object o1, Object o2) {

return (o1 == null ? o2 == null : o1.equals(o2));

}

?

/**

返回指定 collection 中等于指定对象的元素数。更确切地讲,返回 collection 中满足 (o == null ? e == null : o.equals(e)) 的 e 元素的数量。?

?

参数:

c - 在其中确定 o 出现频率的 collection

o - 将确定出现频率的对象?

抛出:?

NullPointerException - 如果 c 为 null

从以下版本开始:?

1.5?

?

*/

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;

}

?

/**

如果两个指定 collection 中没有相同的元素,则返回 true。?

如果将此方法用在不符合 Collection 常规协定的 collection 上,则必须小心。实现可以在任一 collection 上进行迭代,测试元素是否包含在另一个 collection 中(或执行任何等效的计算)。如果任一 collection 使用了一个非标准的相等性测试(比如顺序不是与 equals 一致的 SortedSet,或者 IdentityHashMap 的键集),则两个 collection 都必须使用相同的非标准相等性测试,否则此方法的结果是不确定的。?

?

注意,允许在两个参数中传递相同的 collection,在这种情况下,当且仅当 collection 为空时此方法返回 true。?

?

?

参数:

c1 - 一个 collection

c2 - 一个 collection?

抛出:?

NullPointerException - 如果任一 collection 为 null

从以下版本开始:?

1.5?

?

*/

public static boolean disjoint(Collection<?> c1, Collection<?> c2) {

/*

* We're going to iterate through c1 and test for inclusion in c2.

* If c1 is a Set and c2 isn't, swap the collections. ?Otherwise,

* place the shorter collection in c1. ?Hopefully this heuristic

* will minimize the cost of the operation.

*/

if ((c1 instanceof Set) && !(c2 instanceof Set) || (c1.size() > c2.size())) {

Collection<?> tmp = c1;

c1 = c2;

c2 = tmp;

}

?

for (Object e : c1)

if (c2.contains(e))

return false;

return true;

}

?

/**

将所有指定元素添加到指定 collection 中。可以分别指定要添加的元素,或者将它们指定为一个数组。此便捷方法的行为与 c.addAll(Arrays.asList(elements)) 的行为是相同的,但在大多数实现下,此方法运行起来可能要快得多。?

在分别指定元素时,此方法提供了将少数元素添加到现有 collection 中的一个便捷方式:?

?

? ? Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");

?

参数:

c - 要插入 elements 的 collection

elements - 插入 c 的元素?

返回:

如果 collection 由于调用而发生更改,则返回 true?

抛出:?

UnsupportedOperationException - 如果 c 不支持 add 操作?

NullPointerException - 如果 elements 包含一个或多个 null 值并且 c 不允许使用 null 元素,或者 c 或 elements 为 null?

IllegalArgumentException - 如果 elements 中值的某个属性不允许将它添加到 c 中

从以下版本开始:?

1.5?

另请参见:

Collection.addAll(Collection)

?

*/

public static <T> boolean addAll(Collection<? super T> c, T... elements) {

boolean result = false;

for (T element : elements)

result |= c.add(element);

return result;

}

?

/**

返回指定映射支持的 set。得到的 set 与底层实现映射有相同的顺序、并发性和性能特征。事实上,此工厂方法提供了一个对应于任何 Map 实现的 Set 实现。不必在已经有一个对应 Set 实现(比如 HashMap 或 TreeMap)的 Map 实现上使用此方法。?

每次在此方法返回的 set 上调用方法都将导致在底层实现映射或其 keySet 视图上调用该方法一次,并伴随一个异常。addAll 方法是作为底层实现映射上的 put 调用序列实现的。?

?

在调用此方法时,指定映射必须为空,并且不能在此方法返回之后直接访问。如果将映射创建为空,直接传递给此方法,并且没有保留对该映射的引用,则这些条件都可以得到保证,如以下代码片段所示:?

?

? ?Set<Object> weakHashSet = Collections.newSetFromMap(

? ? ? ?new WeakHashMap<Object, Boolean>());

?

参数:

map - 底层实现映射?

返回:

受映射支持的 set?

抛出:?

IllegalArgumentException - 如果 map 不为空

从以下版本开始:?

1.6?

?

*/

public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {

return new SetFromMap<E>(map);

}

?

private static class SetFromMap<E> extends AbstractSet<E> implements Set<E>, Serializable {

private final Map<E, Boolean> m; // The backing map

private transient Set<E> s; // Its keySet

?

SetFromMap(Map<E, Boolean> map) {

if (!map.isEmpty())

throw new IllegalArgumentException("Map is non-empty");

m = map;

s = map.keySet();

}

?

public void clear() {

m.clear();

}

?

public int size() {

return m.size();

}

?

public boolean isEmpty() {

return m.isEmpty();

}

?

public boolean contains(Object o) {

return m.containsKey(o);

}

?

public boolean remove(Object o) {

return m.remove(o) != null;

}

?

public boolean add(E e) {

return m.put(e, Boolean.TRUE) == null;

}

?

public Iterator<E> iterator() {

return s.iterator();

}

?

public Object[] toArray() {

return s.toArray();

}

?

public <T> T[] toArray(T[] a) {

return s.toArray(a);

}

?

public String toString() {

return s.toString();

}

?

public int hashCode() {

return s.hashCode();

}

?

public boolean equals(Object o) {

return o == this || s.equals(o);

}

?

public boolean containsAll(Collection<?> c) {

return s.containsAll(c);

}

?

public boolean removeAll(Collection<?> c) {

return s.removeAll(c);

}

?

public boolean retainAll(Collection<?> c) {

return s.retainAll(c);

}

?

// addAll is the only inherited implementation

?

private static final long serialVersionUID = 2454657854757543876L;

?

private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {

stream.defaultReadObject();

s = m.keySet();

}

}

?

/**

以后进先出 (Lifo) Queue 的形式返回某个 Deque 的视图。方法 add 被映射到 push,remove 被映射到 pop 等等。在希望使用某一方法获取一个 Queue 并且需要它具有 Lifo 顺序时,此方法很有用。?

每次在此方法返回的队列上调用方法都将导致在底层实现队列上调用该方法一次,并伴随一个异常。addAll 方法是作为底层实现队列上的 addFirst 调用序列实现的。?

?

?

参数:

deque - 队列?

返回:

队列

从以下版本开始:?

1.6?

?

*/

public static <T> Queue<T> asLifoQueue(Deque<T> deque) {

return new AsLIFOQueue<T>(deque);

}

?

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

}

}


读书人网 >编程

热点推荐