Collections是集合类Collection/Map的一个通用工具类
1 Collections静态方法
2 部分源码分析
2.1 局部构造器
由于它所拥有操作集合的方法都是以静态的形式给定的,所以在源码中局部化构造函数,可避免实例化Collections;
private Collections() {
}
2.2 方法阀值
根据阀值,Collections为有些方法(如:二分法查找binarySearch、填充fill、乱序shuffle等)添加了不同的实现机制;
//每个开头单词都代表Collections的对应方法
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;
//二分法查找
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {
//判断list是否为 RandomAccess实例 或者 list的大小是否小于二分法阀值
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
//基于索引的二分法
return Collections.indexedBinarySearch(list, key);
else
//基于迭代器的二分法
return Collections.iteratorBinarySearch(list, key);
}
2.3 不可修改
对原始输入进行封装,并输出不可修改的集合,该集合对接口(可能是Collection)增、删、改方法,以运行时报错UnsupportedOperationException的方式实现。
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
//封装为不可修改集合
return new UnmodifiableCollection<>(c);
}
static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
final Collection<? extends E> c;
UnmodifiableCollection(Collection<? extends E> c) {
if (c==null)
throw new NullPointerException();
this.c = c;
}
//增、删、该将在运行时报错
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
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
//其他方法略.....
}
2.4 同步控制
对原始输入集合进行封装,并输出同步的集合,该集合采用Synchronized字眼加锁;
public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
//封装成同步集合
return new SynchronizedCollection<>(c);
}
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final Collection<E> c;
//钥匙
final Object mutex;
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);
}
//采用 Synchronized进行线程加锁
public int size() {
synchronized (mutex) {return c.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return c.isEmpty();}
}
//其他方法略....
}
2.5 类型检查
对原始输入集合进行封装,并输出包含类型检查的集合(个人觉得适用性不大,因为JDK5之后泛型集合可以在编译时进行类型检查,不存在将不同对象容纳在同一集合的情况发生);
public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type) {
//封装为包含类型检查的集合,该集合在添加元素时会对元素进行类型检查
return new CheckedCollection<>(c, type);
}
2.6 元素复制
其目的是将原列表中的元素复制给目标列表,并要求目标列表的大小比原列表大,而且是从目标列表的0索引开始进行复制作业;
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");
//COPY_THRESHOLD是阀值
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());
}
}
}
3 简单代码测试
package xw.zx.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class CollectionsTest {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("C");list.add("d");
//排序
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);//[a, b, C, d]
//填充
Collections.fill(list, "a");//[a, a, a, a]
//返回不可修改集合
Collection<String> unmodCollection=Collections.unmodifiableCollection(list);
unmodCollection.add("a");//报运行时错误UnsupportedOperationException
}
}