本文出自:http://blog.csdn.net/dt235201314/article/details/78741922
一丶概述
Collections在之前关于集合的文章中有说到Collections是集合工具类,提供一些相关算法,然而从事Android开发,数据基本都由后台处理,很少用到,面试问到话绝对答不上,这里就说说源码与用法。
二丶常见案例
/**
* <pre>
* author : JinBiao
* CSDN : http://my.csdn.net/DT235201314
* time : 2017/12/11
* desc : 集合工具类Collections 常见方法demo
* version: 1.0
* </pre>
*/
public class CollectionsDemo {
public static void main(String[] args){
ArrayList nums=new ArrayList();
nums.add(12);
nums.add(-5);
nums.add(8);
Collections.sort(nums);//[-5, 8, 12]
System.out.println(nums);
nums.add(7);
Collections.reverse(nums);
System.out.println(nums);//[7, 12, 8, -5]
Collections.shuffle(nums);//随机排序
System.out.println(nums);//假定此刻为:[12, 7, -5, 8]
nums.add(10);
System.out.println(nums);//[12, 8, 7, -5, 10]
Collections.rotate(nums, 3);
//rotate操作,正数是将nums的后3个数整体搬移到前面,负数是将前面3个数整体搬移到后面。
System.out.println(nums);//[7, -5, 10, 12, 8]
Collections.rotate(nums, -2);
System.out.println(nums);//[10, 12, 8, 7, -5]
//查找替换操作
nums.add(7);
System.out.println(Collections.max(nums));//12
System.out.println(Collections.min(nums));//-5
Collections.replaceAll(nums, 7, 9);//将num中所有7替换为9[10, 12, 8, 9, -5, 9]
System.out.println(nums);
System.out.println(Collections.frequency(nums, 9));//2
Collections.sort(nums);//只有排序了才能用二分查找
System.out.println(Collections.binarySearch(nums, 10));//4
}
}
/**运行结果:
[-5, 8, 12]
[7, 12, 8, -5]
[7, 12, -5, 8]
[7, 12, -5, 8, 10]
[-5, 8, 10, 7, 12]
[10, 7, 12, -5, 8]
12
-5
[10, 9, 12, -5, 8, 9]
2
4
*/
三丶源码分析
(1)sort()排序方法
/**
* List中的所有元素必须实现Compareable接口,即每个 元素必须是可比的。
* 算法的实现原理为: 把指定的List转化为一个对象数组,对数组进行排序,然后迭代List的每一个元素,
* 在同样的位置重新设置数组中排好序的元素
*/
public static <T extends Comparable<? super T>> void sort(List<T> list) {
if (list.getClass() == ArrayList.class) {
//transient Object[] elementData
// 用transient关键字标记的成员变量不参与序列化过程。
Arrays.sort(((ArrayList) list).elementData, 0, list.size());
return;
}
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}
/**
* 传一个实现了Comparator接口的对象进来。 c.compare(o1,o2);来比较两个元素
*/
public static <T> void sort(List<T> list, Comparator<? super T> c) {
if (list.getClass() == ArrayList.class) {
Arrays.sort(((ArrayList) list).elementData, 0, list.size(), (Comparator) c);
return;
}
Object[] a = list.toArray();
Arrays.sort(a, (Comparator)c);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}
Comparable && Comparator区别与源码分析
(2)binarySearch()二分查找方法
/**
* 使用二分查找在指定List中查找指定元素key。 List中的元素必须是有序的。如果List中有多个key,不能确保哪个key值被找到。
* 如果List不是有序的,返回的值没有任何意义
*
* 对于随机访问列表来说,时间复杂度为O(log(n)),比如1024个数只需要查找log2(1024)=10次,
* log2(n)是最坏的情况,即最坏的情况下都只需要找10次
* 对于链表来说,查找中间元素的时间复杂度为O(n),元素比较的时间复杂度为O(log(n))
*
* @return 查找元素的索引。如果返回的是负数表明找不到此元素,但可以用返回值计算
* 应该将key插入到集合什么位置,任然能使集合有序(如果需要插入key值的话)。 公式:point = -i - 1
*
*/
public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
else
return Collections.iteratorBinarySearch(list, key);
}
/**
* 使用索引化二分查找。 size小于5000的链表也用此方法查找
*/
private static <T>
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
int low = 0;
int high = list.size()-1;
while (low <= high) {
// >>>1:无符号右移,忽略符号位,空位都以0补齐
int mid = (low + high) >>> 1;//相当于无符号除以2
Comparable<? super T> midVal = list.get(mid);
// 指定元素与中间值比较
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
/**
* 迭代式二分查找,线性查找,依次查找得中间值
*/
private static <T>
int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
{
int low = 0;
int high = list.size()-1;
ListIterator<? extends Comparable<? super T>> i = list.listIterator();
while (low <= high) {
int mid = (low + high) >>> 1;
Comparable<? super T> midVal = get(i, mid);
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
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;
}
/**
* 提供实现了Comparator接口的对象比较元素
*/
public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
if (c==null)
return binarySearch((List<? extends Comparable<? super T>>) list, key);
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key, c);
else
return Collections.iteratorBinarySearch(list, key, c);
}
private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
int low = 0;
int high = l.size()-1;
while (low <= high) {
int mid = (low + high) >>> 1;
T midVal = l.get(mid);
int cmp = c.compare(midVal, key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
int low = 0;
int high = l.size()-1;
ListIterator<? extends T> i = l.listIterator();
while (low <= high) {
int mid = (low + high) >>> 1;
T midVal = get(i, mid);
int cmp = c.compare(midVal, key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
(3)reverse()反序方法
/**
* 逆序排列指定列表中的元素
*/
public static void reverse(List<?> list) {
int size = list.size();
//size小于18的链表或是基于随机访问的列表
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
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);
}
}
}
/**
* 交换List中两个位置的值
*/
public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
(4)shuffle()随机混排方法
/**
* 对指定列表中的元素进行混排
*/
public static void shuffle(List<?> list) {
Random rnd = r;
if (rnd == null)
r = rnd = new Random(); // harmless race.
shuffle(list, rnd);
}
private static Random r;
/**
* 提供一个随机数生成器对指定List进行混排
* 基本算法思想为: 逆向遍历list,从最后一个元素到第二个元素,然后重复交换当前位置 与随机产生的位置的元素值。
* 如果list不是基于随机访问并且其size>5,会先把List中的复制到数组中, 然后对数组进行混排,再把数组中的元素重新填入List中。
* 这样做为了避免迭代器大跨度查找元素影响效率
*/
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--)
// 从i-1个位置开始与随机位置元素交换值
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
for (int i=size; i>1; i--)
// 对数组进行混排
swap(arr, i-1, rnd.nextInt(i));
// 然后把数组中的元素重新填入List
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
/**
* 交换数组中两个位置的值
*/
private static void swap(Object[] arr, int i, int j) {
Object tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
(5)fill()替换方法
/**
* 用obj替换List中的所有元素 size<25 依次遍历赋值即可
*/
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);
}
}
}
(6)copy()复制方法
/**
* 复制源列表的所有元素到目标列表, 如果src.size > dest.size 将抛出一个异常 如果src.size < dest.size
* dest中多出的元素将不受影响 同样是依次遍历赋值
*/
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
int srcSize = src.size();
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest");
if (srcSize < COPY_THRESHOLD ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i<srcSize; i++)
dest.set(i, src.get(i));
} else {
// 一个链表一个线性表也可以用迭代器赋值
ListIterator<? super T> di=dest.listIterator();
ListIterator<? extends T> si=src.listIterator();
for (int i=0; i<srcSize; i++) {
di.next();
di.set(si.next());
}
}
}
(7)min()最小值法
/**
* 返回集合中的最小元素。前提是其中的元素都是可比的,即实现了Comparable接口
* 反正要依次遍历完所有元素,所以直接用了迭代器
*/
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) < 0)
candidate = next;
}
return candidate;
}
/**
* 根据提供的比较器求最小元素
*/
public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)min((Collection) coll);
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (comp.compare(next, candidate) < 0)
candidate = next;
}
return candidate;
}
(8)max()最大值方法
/**
*最大元素方法 同最小值
*/
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;
}
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)max((Collection) coll);
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (comp.compare(next, candidate) > 0)
candidate = next;
}
return candidate;
}
(9)rotate()轮换方法
/**
* 旋转移位List中的元素通过指定的distance。每个元素移动后的位置为: (i +
* distance)%list.size.此方法不会改变列表的长度
* 比如,类表元素为: [t, a, n, k, s , w] 执行Collections.rotate(list, 2)或
* Collections.rotate(list, -4)后, list中的元素将变为 [s, w, t, a, n ,
* k]。可以这样理解:正数表示向后移,负数表示向前移
*/
public static void rotate(List<?> list, int distance) {
if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
rotate1(list, distance);
else
rotate2(list, distance);
}
private static <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;
// 超出size就减去size
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);
}
(10)replaceAll()替换,有改变返回true
/**
* 把指定集合中所有与oladVal相等的元素替换成newVal 只要list发生了改变就返回true
*/
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;
}
(11)int indexOfSubList 是否包含字符串
/**
*
* target是否是source的子集,如果是返回target第一个元素的索引, 否则返回-1。
* 其实这里和串的模式匹配差不多。这里使用的是基本的回溯法。
*
*/
public static int indexOfSubList(List<?> source, List<?> target) {
int sourceSize = source.size();
int targetSize = target.size();
int maxCandidate = sourceSize - targetSize;
if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
(source instanceof RandomAccess&&target instanceof RandomAccess)) {
nextCand:
for (int candidate = 0; candidate <= maxCandidate; candidate++) {
for (int i=0, j=candidate; i<targetSize; i++, j++)
if (!eq(target.get(i), source.get(j)))
continue nextCand; // Element mismatch, try next cand
return candidate; // All elements of candidate matched target
}
} else { // Iterator version of above algorithm
ListIterator<?> si = source.listIterator();
nextCand:
for (int candidate = 0; candidate <= maxCandidate; candidate++) {
ListIterator<?> ti = target.listIterator();
for (int i=0; i<targetSize; i++) {
if (!eq(ti.next(), si.next())) {
// Back up source iterator to next candidate
for (int j=0; j<i; j++)
si.previous();
continue nextCand;
}
}
return candidate;
}
}
return -1; // No candidate matched the target
}
static boolean eq(Object o1, Object o2) {
return o1==null ? o2==null : o1.equals(o2);
}
(12)lastIndexOfSubList
/**
* 如果有一个或多个字串,返回最后一个出现的子串的第一个元素的索引
*/
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
}
(13)unmodifiable***
返回不可变集合,在修改时抛出异常
/**
* 返回一个关于指定集合的不可修改的集合。 任何试图修改该视图的操作都将抛出一个UnsupportedOperationException
* Collection返回的视图的equals方法不是调用底层集合的equals方法
* 而是继承了Object的equals方法。hashCode方法也是一样的。 因为Set和List的equals方法并不相同。
*/
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
return new UnmodifiableCollection<>(c);
}
/**
* @serial include
*/
static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 1820017752578914078L;
final Collection<? extends E> c;
UnmodifiableCollection(Collection<? extends E> c) {
if (c==null)
throw new NullPointerException();
this.c = c;
}
public int size() {return c.size();}
public boolean isEmpty() {return c.isEmpty();}
public boolean contains(Object o) {return c.contains(o);}
public Object[] toArray() {return c.toArray();}
public <T> T[] toArray(T[] a) {return c.toArray(a);}
public String toString() {return c.toString();}
public Iterator<E> iterator() {
return new Iterator<E>() {
private final Iterator<? extends E> i = c.iterator();
public boolean hasNext() {return i.hasNext();}
public E next() {return i.next();}
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
// Use backing collection version
i.forEachRemaining(action);
}
};
}
public boolean add(E e) {
throw new UnsupportedOperationException();
}
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
public boolean containsAll(Collection<?> coll) {
return c.containsAll(coll);
}
public boolean addAll(Collection<? extends E> coll) {
throw new UnsupportedOperationException();
}
public boolean removeAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public boolean retainAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
}
// Override default methods in Collection
@Override
public void forEach(Consumer<? super E> action) {
c.forEach(action);
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
@Override
public Spliterator<E> spliterator() {
return (Spliterator<E>)c.spliterator();
}
@SuppressWarnings("unchecked")
@Override
public Stream<E> stream() {
return (Stream<E>)c.stream();
}
@SuppressWarnings("unchecked")
@Override
public Stream<E> parallelStream() {
return (Stream<E>)c.parallelStream();
}
}
其它类型都继承,略
(14)synchronized***同步集合
如果你需要将一个集合的所有操作都设置为线程安全的,Collections.synchronizedXXX() 是一种方法
/**
*同步包装
* 返回一个线程安全的集合 但是当用户遍历此集合时,需要手动进行同步 Collection c =
* Collections.synchronizedCollection(myCollection); ... synchronized(c) {
* Iterator i = c.iterator(); // Must be in the synchronized block while
* (i.hasNext()) foo(i.next()); }
*
*/
public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
return new SynchronizedCollection<>(c);
}
static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {
return new SynchronizedCollection<>(c, mutex);
}
/**
* @serial include
*/
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final Collection<E> c; // 返回的集合
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);
}
public int size() {
synchronized (mutex) {return c.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return c.isEmpty();}
}
public boolean contains(Object o) {
synchronized (mutex) {return c.contains(o);}
}
public Object[] toArray() {
synchronized (mutex) {return c.toArray();}
}
public <T> T[] toArray(T[] a) {
synchronized (mutex) {return c.toArray(a);}
}
public Iterator<E> iterator() {
return c.iterator(); // Must be manually synched by user!
}
public boolean add(E e) {
synchronized (mutex) {return c.add(e);}
}
public boolean remove(Object o) {
synchronized (mutex) {return c.remove(o);}
}
public boolean containsAll(Collection<?> coll) {
synchronized (mutex) {return c.containsAll(coll);}
}
public boolean addAll(Collection<? extends E> coll) {
synchronized (mutex) {return c.addAll(coll);}
}
public boolean removeAll(Collection<?> coll) {
synchronized (mutex) {return c.removeAll(coll);}
}
public boolean retainAll(Collection<?> coll) {
synchronized (mutex) {return c.retainAll(coll);}
}
public void clear() {
synchronized (mutex) {c.clear();}
}
public String toString() {
synchronized (mutex) {return c.toString();}
}
// Override default methods in Collection
@Override
public void forEach(Consumer<? super E> consumer) {
synchronized (mutex) {c.forEach(consumer);}
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
synchronized (mutex) {return c.removeIf(filter);}
}
@Override
public Spliterator<E> spliterator() {
return c.spliterator(); // Must be manually synched by user!
}
@Override
public Stream<E> stream() {
return c.stream(); // Must be manually synched by user!
}
@Override
public Stream<E> parallelStream() {
return c.parallelStream(); // Must be manually synched by user!
}
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {s.defaultWriteObject();}
}
}
(15)checked***
有类型检查的集合
/**
* 返回一个动态的类型安全的集合。任何试图插入错误类型的元素的操作将立刻抛出 ClassCastException
* 动态类型安全视图的一个主要作用是用作debug调试, 因为它能正确反映出出错的位置。 例如:ArrayList<String> strings =
* new ArrayList<String>(); ArrayList rawList = strings; rawList.add(new
* Date()); add方法并不进行类型检查,所以存入了非String的对象。只有在重新获取该对象 转化为String类型的时候才抛出异常。
* 而动态类型安全的集合能在add时就会抛出ClassCastException。 这种方法的优点是错误可以在正确的位置被报告
*/
public static <E> Collection<E> checkedCollection(Collection<E> c,
Class<E> type) {
return new CheckedCollection<>(c, type);
}
@SuppressWarnings("unchecked")
static <T> T[] zeroLengthArray(Class<T> type) {
return (T[]) Array.newInstance(type, 0);
}
/**
* @serial include
*/
static class CheckedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 1578914078182001775L;
final Collection<E> c;
final Class<E> type;
void typeCheck(Object o) {
if (o != null && !type.isInstance(o))
throw new ClassCastException(badElementMsg(o));
}
private String badElementMsg(Object o) {
return "Attempt to insert " + o.getClass() +
" element into collection with element type " + type;
}
CheckedCollection(Collection<E> c, Class<E> type) {
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 void clear() { c.clear(); }
public boolean containsAll(Collection<?> coll) {
return c.containsAll(coll);
}
public boolean removeAll(Collection<?> coll) {
return c.removeAll(coll);
}
public boolean retainAll(Collection<?> coll) {
return c.retainAll(coll);
}
public Iterator<E> iterator() {
// JDK-6363904 - unwrapped iterator could be typecast to
// ListIterator with unsafe set()
final Iterator<E> it = c.iterator();
return new Iterator<E>() {
public boolean hasNext() { return it.hasNext(); }
public E next() { return it.next(); }
public void remove() { it.remove(); }};
// Android-note: Should we delegate to it for forEachRemaining ?
}
public boolean add(E e) {
typeCheck(e);
return c.add(e);
}
private E[] zeroLengthElementArray = null; // Lazily initialized
private E[] zeroLengthElementArray() {
return zeroLengthElementArray != null ? zeroLengthElementArray :
(zeroLengthElementArray = zeroLengthArray(type));
}
@SuppressWarnings("unchecked")
Collection<E> checkedCopyOf(Collection<? extends E> coll) {
Object[] a = null;
try {
E[] z = zeroLengthElementArray();
a = coll.toArray(z);
// Defend against coll violating the toArray contract
if (a.getClass() != z.getClass())
a = Arrays.copyOf(a, a.length, z.getClass());
} catch (ArrayStoreException ignore) {
// To get better and consistent diagnostics,
// we call typeCheck explicitly on each element.
// We call clone() to defend against coll retaining a
// reference to the returned array and storing a bad
// element into it after it has been type checked.
a = coll.toArray().clone();
for (Object o : a)
typeCheck(o);
}
// A slight abuse of the type system, but safe here.
return (Collection<E>) Arrays.asList(a);
}
public boolean addAll(Collection<? extends E> coll) {
// Doing things this way insulates us from concurrent changes
// in the contents of coll and provides all-or-nothing
// semantics (which we wouldn't get if we type-checked each
// element as we added it)
return c.addAll(checkedCopyOf(coll));
}
// Override default methods in Collection
@Override
public void forEach(Consumer<? super E> action) {c.forEach(action);}
@Override
public boolean removeIf(Predicate<? super E> filter) {
return c.removeIf(filter);
}
@Override
public Spliterator<E> spliterator() {return c.spliterator();}
@Override
public Stream<E> stream() {return c.stream();}
@Override
public Stream<E> parallelStream() {return c.parallelStream();}
}
(16)empty***永远的空集
/**
* 不可变的空集
* 不可造作
*/
public static <T> ListIterator<T> emptyListIterator() {
return (ListIterator<T>) EmptyListIterator.EMPTY_ITERATOR;
}
private static class EmptyListIterator<E>
extends EmptyIterator<E>
implements ListIterator<E>
{
static final EmptyListIterator<Object> EMPTY_ITERATOR
= new EmptyListIterator<>();
public boolean hasPrevious() { return false; }
public E previous() { throw new NoSuchElementException(); }
public int nextIndex() { return 0; }
public int previousIndex() { return -1; }
public void set(E e) { throw new IllegalStateException(); }
public void add(E e) { throw new UnsupportedOperationException(); }
}
(17)singleton***永远含一个元素的集合
/**
* 返回只包含一个元素的不可变的集合
*/
public static <E> Set<E> singleton(E o) {
return new SingletonSet<>(o);
}
static <E> Iterator<E> singletonIterator(final E e) {
return new Iterator<E>() {
private boolean hasNext = true;
public boolean hasNext() {
return hasNext;
}
public E next() {
if (hasNext) {
hasNext = false;
return e;
}
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
if (hasNext) {
action.accept(e);
hasNext = false;
}
}
};
}
(18)nCopies 返回只包含某子串集合
/**
* 返回一个包含N个o元素的不可变的集合
*
* @param n
* 添加的指定元素的个数
* @param o
* 被重复添加的元素
*/
public static <T> List<T> nCopies(int n, T o) {
if (n < 0)
throw new IllegalArgumentException("List length = " + n);
return new CopiesList<>(n, o);
}
/**
* @serial include
*/
private static class CopiesList<E>
extends AbstractList<E>
implements RandomAccess, Serializable
{
private static final long serialVersionUID = 2739099268398711800L;
final int n;
final E element;
CopiesList(int n, E e) {
assert n >= 0;
this.n = n;
element = e;
}
public int size() {
return n;
}
public boolean contains(Object obj) {
return n != 0 && eq(obj, element);
}
public int indexOf(Object o) {
return contains(o) ? 0 : -1;
}
public int lastIndexOf(Object o) {
return contains(o) ? n - 1 : -1;
}
public E get(int index) {
if (index < 0 || index >= n)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+n);
return element;
}
public Object[] toArray() {
final Object[] a = new Object[n];
if (element != null)
Arrays.fill(a, 0, n, element);
return a;
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
final int n = this.n;
if (a.length < n) {
a = (T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), n);
if (element != null)
Arrays.fill(a, 0, n, element);
} else {
Arrays.fill(a, 0, n, element);
if (a.length > n)
a[n] = null;
}
return a;
}
public List<E> subList(int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > n)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
return new CopiesList<>(toIndex - fromIndex, element);
}
// Override default methods in Collection
@Override
public Stream<E> stream() {
return IntStream.range(0, n).mapToObj(i -> element);
}
@Override
public Stream<E> parallelStream() {
return IntStream.range(0, n).parallel().mapToObj(i -> element);
}
@Override
public Spliterator<E> spliterator() {
return stream().spliterator();
}
}
Collections源码就分享到这里,还是挺有意思的
三丶参考文章
网友评论