Collections源码

1、Collections类介绍

类Collections以静态方法的方式提供了很多通用算法和功能,这些功能大概分为两类

  • 对容器接口对象进行操作

    • 查找和替换
    • 排序和调整顺序
    • 添加和修改
  • 返回一个容器接口对象

    • 适配器:将其他类型的数据转换为容器接口对象
    • 装饰器:修饰一个给定容器接口对象,增加某些性质

2、对接口对象的操作

2.1、查找和替换

二分查找

 public static <T>
    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
     //实现了RandomAceess接口,RandomAccess是一个空接口,表明一个特征,在算法实现的时候可以体现
     //这里就利用到了
        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
            //基于索引查找
            return Collections.indexedBinarySearch(list, key);
        else
            //基于迭代器查找
            return Collections.iteratorBinarySearch(list, key);
    }

//数组的二分查找算法,效率为O(log2N)
 private static <T>
    int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
        int low = 0;
        int high = list.size()-1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            Comparable<? super T> midVal = list.get(mid);
            int cmp = midVal.compareTo(key);

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found
    }

//;链表的二分查找,比较的次数为O(lOg2N),遍历移动的次数为O(N)
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
    }





2.2、查找最大值、最小值

实现思路很简单:通过迭代器进行比较

 //查找最大值与最小值的方法
    public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
       //通过迭代器进行比较
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        //遍历Collection接口
        while (i.hasNext()) {
            T next = i.next();

            if (next.compareTo(candidate) > 0)
                candidate = next;
        }
        return candidate;
    }


   @SuppressWarnings({"unchecked", "rawtypes"})
    public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
        if (comp==null)
            return (T)max((Collection) coll);

        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (comp.compare(next, candidate) > 0)
                candidate = next;
        }
        return candidate;
    }


2.3、查找元素出现的次数

//返回元素o在容器中出现的次数
    //实现思路很简单,就是通过迭代器进行比较
    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;
    }

2.4、查找list出现的位子

//暴力破解:将target列表与source从第一个元素开始的列表逐个元素进行比较
    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
    }

2.5、排序

@SuppressWarnings("unchecked")
    //排序,内部通过Arrays.sort实现
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        //先将List元素复制到一个数组中
        Object[] a = list.toArray();
        //使用Arrays.sort进行排序
        Arrays.sort(a);
        ListIterator<T> i = list.listIterator();
        //排序后,再复制回list
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set((T)a[j]);
        }
    }




2.6、交换位置

 //交换第i和第j个元素的内容
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static void swap(List<?> list, int i, int j) {
        // instead of using a raw type here, it's possible to capture
        // the wildcard but it will require a call to a supplementary
        // private method
        final List l = list;
        l.set(i, l.set(j, l.get(i)));
    }

2.7、反转列表

//反转列表的顺序
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static void reverse(List<?> list) {
        int size = list.size();
        //实现思路:
        //将第一个和最后一个交换,第二个和倒数第二个交换,以此类推,直到中间两个元素交换完毕
        //如果实现了RandomAccess接口或列表比较大小。根据索引位置使用swap方法进行交换
        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定位待交换的元素
            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);
            }
        }
    }

2.8、随机化重排

 //随机化重排
    public static void shuffle(List<?> list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }

//随机化重排
    //从后往前遍历列表,逐个给每个位置重新赋值,值从前面的末尾重新赋值的元素随机挑选
    //如果列表实现了RandomAceess接口,或者列表比较小,直接使用前面的swap方法进行交换
    //否则,先将列表内容复制到一个数组中,洗牌,再复制回列表
    public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();

            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));

            // Dump array back into list
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }




3、返回一个容器接口对象

3.1、适配器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9w61kth0-1582875105378)(images/39.png)]

3.1.1、空容器的方法

返回一个静态不可变对象,可以节省创建新对象内存和时间开销

public static <T> Iterator<T> emptyIterator() {
        return (Iterator<T>) EmptyIterator.EMPTY_ITERATOR;
    }


private static class EmptyIterator<E> implements Iterator<E> {

    
public static <T> ListIterator<T> emptyListIterator() {

    
    public static final <T> Set<T> emptySet() {
        return (Set<T>) EMPTY_SET;
    }
       

3.1.2、单一对象方法

将一个对象转还为一个标准的容器接口对象

   public static <T> Set<T> singleton(T o) {
        return new SingletonSet<>(o);
    }

 public static <T> List<T> singletonList(T o) {
        return new SingletonList<>(o);
    }



3.2、装饰器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-61KEWmbX-1582875105379)(images/40.png)]

3.2.1、写安全

生成Collection内部的静态类,所有写方法会抛出异常

    public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
        return new UnmodifiableCollection<>(c);
    }


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



3.2.2、类型安全

 public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
        return new CheckedSet<>(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(); }
    }

3。2.3、线程安全

这些方法都是通过给所有容器方法加锁来实现的。

  public static <T> List<T> synchronizedList(List<T> list) {
        return (list instanceof RandomAccess ?
                new SynchronizedRandomAccessList<>(list) :
                new SynchronizedList<>(list));
    }

//注意所有方法都加锁了

    /**
     * @serial include
     */
    static class SynchronizedList<E>
            extends SynchronizedCollection<E>
            implements List<E> {
        private 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) {
            if (this == o)
                return true;
            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<>(list.subList(fromIndex, toIndex),
                        mutex);
            }
        }

        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            synchronized (mutex) {list.replaceAll(operator);}
        }
        @Override
        public void sort(Comparator<? super E> c) {
            synchronized (mutex) {list.sort(c);}
        }

        /**
         * 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<>(list)
                    : this);
        }
    }



发布了198 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/ZHOUJIAN_TANK/article/details/104557634
今日推荐