当我们在聊Collections

本文出自: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源码就分享到这里,还是挺有意思的

三丶参考文章

Java 常用工具类 Collections 源码分析

Collections源码

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,373评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,732评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,163评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,700评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,036评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,425评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,737评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,421评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,141评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,398评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,908评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,276评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,907评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,018评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,772评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,448评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,325评论 2 261

推荐阅读更多精彩内容