AbstractCollection<E>源码解读

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuhuanchao/article/details/51208475
package java.util;
//提供 Collection 接口的骨干实现,以最大限度地减少了实现此接口所需的工作
public abstract class AbstractCollection<E> implements Collection<E> {

	//每个实现该抽象类的,需要提供一个空的构造函数
	public AbstractCollection() {
		
	}
	
	//返回迭代器 
	public abstract  Iterator<E> iterator();
	
	//容量大小
	@Override
	public abstract int size();

	//直接调用size()方法返回大小,如果是0就认为是空集合,size()方法没有实现,怎么可以调用呢?因为这个是抽象类,不可以实例化的,具体的时候调用的是子类中的实现
	@Override
	public boolean isEmpty() {
		return size()==0;
	}

	//遍历集合,如果找到了就返回true,在没找到的情况下是要遍历整个集合的.对于null值的情况一定要放在if里面,而不能放在else里面.
	@Override
	public boolean contains(Object o) {
		Iterator<E> it = iterator();
		if(o==null){
			while(it.hashNext()){
				if(it.next()==null)
					return true;
			}
		}else{
			while(it.hashNext()){
				if(o.equals(it.next()))
					return true;
			}
		}
		return false;
	}

	//返回数组,先生成一个和集合一样大小的数组,然后通过遍历赋值.
	@Override
	public Object[] toArray() {
		Object[] object = new Object[size()];
		Iterator<E> it = iterator();
		for(int i=0;i<object.length;i++){
			if(!it.hashNext())
				return Arrays.copyOf(object,i);
			object[i] = it.next();
		}
		return it.hashNext() ? finishToArray(object,it) : object;
	}

	@Override
	public <T> T[] toArray(T[] a) {
		int size = size();
		//判断集合大小和a的大小,如果a的大小足够大,则用a来存储元素,否则新生成一个数组,注意是用反射生成的,所以其元素类型能保证 
		T[] r = a.length >= size ? a : (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
		Iterator<E> it =iterator();
		for(int i=0;i<r.length;i++){
			if(!it.hashNext()){
				if(a==r){
					r[i] = null;
				}else if(a.length<i){
					return Arrays.copyOf(r,i);
				}else {
					System.arraycopy(r,0,a,0,i);
					if(a.length>i){
						a[i] =null;
					}
				}
				return a;
			}
			r[i] = (T)it.next();
		}
		return it.hashNext() ? finishToArray(r, it) : r;
	}

	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;
	
	//拷贝复制集合中的元素到数组中  
    private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
		int i = r.length;
		while(it.hashNext()){
			int cap = r.length;
			if(i==cap){//进行扩容
				int newCap = cap+(cap >> 1)+1;//扩容原集合长度的2倍+1
				if(newCap - MAX_ARRAY_SIZE>0){//大于最大的元素
					newCap = hugeCapacity(cap+1);//调整到合适的数据,数组的大小不能超过Integer.MAX_VALUE  
				}
				r = Arrays.copyOf(r,newCap);//执行数据拷贝
			}
			r[i++] = (T)it.next();//扩容完毕,复制数据
		}
		return (i==r.length)? r : Arrays.copyOf(r,i);//返回数组
	}
	
    //调整数组大小,最大不能超过Integer.MAX_VALUE 
	private static int hugeCapacity(int minCapacity) {
		if(minCapacity<0){
			throw new OutOfMemoryError("Required array size too large");
		}
		return (minCapacity>MAX_ARRAY_SIZE)?Integer.MAX_VALUE : MAX_ARRAY_SIZE;
	}

	/**
	 * 这个方法提供了实现,但是是直接抛出一个异常,和未实现的方法是有区别的,
	 * 非抽象子类中可以不重写这个方法,如果子类不想支持这个操作的话,而未实现的方法子类必须实现,否则编译同不过
	 */
	//添加元素,目前不支持
	@Override
	public boolean add(E e) {
		throw new UnsupportedOperationException();
	}

	/**
	 * 这个方法和contians方法基本一样,多了一条e.remove语句而已.
	 * @param o
	 * @return
	 */
	//删除元素,这里是通过迭代器的删除操作来删除元素  
	@Override
	public boolean remove(Object o) {
		Iterator<E> it = iterator();//获得迭代器,在迭代过程中做操作  
		if(o==null){
			while(it.hashNext()){//是否有下一个元素  
				if(it.next()==null){//比较元素内容  
					it.remove();
					return true;
				}
			}
		}else{
			while(it.hashNext()){
				if(it.next()==o){
					it.remove();
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 这个方法比较简洁,但是时间复杂度是m*n,
	 * 通过检查没一个元素是否在集合中,如果发现一个不在直接返回false.
	 * 可以看出返回true的情况花的时间比返回false要多.
	 */
	//判断c中的所有元素是否在集合中
	@Override
	public boolean containsAll(Collection<?> c) {
		for(Object e : c){//c继承了Iterable接口,可以用foreach方法  
			if(!contains(e)){
				return false;
			}
		}
		return true;
	}

	/**
	 * 这里是通过一个一个加入集合的,同样这里的add方法是没有实现的,要注意的一点是,
	 * 只要加入了至少一个元素函数就返回true,表示原来的集合有变化.
	 */
	//添加所有的元素到集合中,其实这个操作也是没实现的
	@Override
	public boolean addAll(Collection<? extends E> c) {
		boolean modified = false;
		for(E e :c){
			if(add(e)){//添加操作
				modified = true;
			}
		}
		return modified;
	}

	/**
	 * 这个方法对集合中的每一个元素判断,如果在集合c中就删除,
	 * 相同值的会被一并删除,删除至少一个元素就返回true.
	 */
	//执行集合的交集操作 
	@Override
	public boolean removeAll(Collection<?> c) {
		boolean modified = false;
		Iterator<E> it = iterator();//获得迭代器
		while(it.hashNext()){
			if(c.contains(it.next())){//包含在内部
				it.remove();
				modified = true;
			}
		}
		return modified;
	}

	/**
	 * 删除集合不想同的元素
	 */
	//求集合的异或操作  
	@Override
	public boolean retainAll(Collection<?> c) {
		boolean modified = false;
		Iterator<E> it = iterator(); //获得迭代器  
		while(it.hashNext()){
			if(!c.contains(it.next())){ //不包含在集合c中
				it.remove();
				modified = true;
			}
		}
		return modified;
	}

	/**
	 * 这个方法把集合清空,不过这个方法效率显得比较低,
	 * 清空应该不需要遍历集合,不过子类可以重写整个方法.
	 */
	 //通过迭代器打印集合 
	@Override
	public void clear() {
		Iterator<E> it = iterator();
		while(it.hashNext()){
			it.next();
			it.remove(); //迭代器的删除操作 
		}
	}

	/**
	 * 最后一个方法了,就是把所有的元素用[]括起来返回,元素间用", "分隔.这里唯一注意的是集合可以包含自己,
	 * 如果没有判断就成死循环了
	 * @return
	 */
	public String toString(){
		StringBuffer buf  = new StringBuffer();
		buf.append("[");
		Iterator<E> it = iterator();
		boolean hashNext = it.hashNext();
		while(it.hashNext()){
			Object o = it.next();
			buf.append(o == this ? "(this Collection)" : String.valueOf(o));
			hashNext = it.hashNext();
			if(hashNext){
				buf.append(",");
			}
		}
		buf.append("]");
		return buf.toString();
	}
}

猜你喜欢

转载自blog.csdn.net/liuhuanchao/article/details/51208475