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