Java之Collections工具类方法使用以及源码分析(三)


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

    public static <E> Collection<E> checkedCollection(Collection<E> c,Class<E> type)
调用该方法时候会进行类型检查,如果类型不匹配抛出ClassCastException异常。



package com.daxin.collections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

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

	public static void main(String[] args) {

		ArrayList<Integer> list = new ArrayList<>();

		for (int i = 1; i <= 5; i++) {

			list.add(i);
		}

		Collection<Integer> view = Collections.checkedCollection(list, Integer.class);

		System.out.println(view);

		view.add(11);
		view.add(12);
		view.add(13);

		System.out.println(view);

		System.out.println(list);

	}

}

 java.util.Collections.checkedCollection(Collection<Integer>, Class<Integer>)的实现:


    public static <E> Collection<E> checkedCollection(Collection<E> c,
                                                      Class<E> type) {
        return new CheckedCollection<>(c, type);
    }

 CheckedCollection的实现;


    /**
     * @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() {
            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(); }};
        }

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

 注意查看add方法,进行了类型检查:

       public boolean add(E e) {
            typeCheck(e);
            return c.add(e);
        }


 查看typeCheck方法实现:

      void typeCheck(Object o) {
            if (o != null && !type.isInstance(o))
                throw new ClassCastException(badElementMsg(o));
        }

代码很简单,不做解释!!


 static <E> List<E>  checkedList(List<E> list, Class<E> type) 
          返回指定列表的一个动态类型安全视图。 

static <K,V> Map<K,V>  checkedMap(Map<K,V> m, Class<K> keyType, Class<V> valueType) 
          返回指定映射的一个动态类型安全视图。 

static <E> Set<E>  checkedSet(Set<E> s, Class<E> type) 
          返回指定 set 的一个动态类型安全视图。 

static <K,V> SortedMap<K,V>  checkedSortedMap(SortedMap<K,V> m, Class<K> keyType, Class<V> valueType) 
          返回指定有序映射的一个动态类型安全视图。 

static <E> SortedSet<E>  checkedSortedSet(SortedSet<E> s, Class<E> type) 
          返回指定有序 set 的一个动态类型安全视图。  

以上方法类似,也不解释了。



















评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值