java源码 -- AbstractCollection抽象类
Posted 王大军
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java源码 -- AbstractCollection抽象类相关的知识,希望对你有一定的参考价值。
简介
AbstractCollection是一个抽象类,它实现了Collection中除了iterator()和size()之外的所有方法。AbstractCollection的主要作用是方便其他类实现Collection.,比如ArrayList、LinkedList等。它们想要实现Collection接口,通过集成AbstractCollection就已经实现大部分方法了,再实现一下iterator()和size()即可。
方法如下:
public abstract Iterator<E> iterator();
public abstract int size();
public boolean isEmpty() { return size() == 0; }
public boolean contains(Object o) { }
public boolean contains(Object o) { Iterator<E> it = iterator(); /* 获得 Iterator 对象 */ if (o == null) { /* o 为 null */ while (it.hasNext()) /* 遍历是否含有 null */ if (it.next() == null) return true; } else { /* o 不为 null(是某个对象) */ while (it.hasNext()) /* 遍历并按照 equals() 方法比较 */ if (o.equals(it.next())) return true; } return false; }
public Object[] toArray() { }
public Object[] toArray() { Object[] r = new Object[size()]; /* 根据 collection 大小 new 一个数组 */ Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { /* 遍历实例化的数组 */ /* 下面这个判断为 true 的时机是: */ /* 多线程情况下,collection 数量在遍历过程中减少,提前终止 */ if (! it.hasNext()) return Arrays.copyOf(r, i); /* 返回一个新数组 */ r[i] = it.next(); } /* List 数量在遍历过程中增加,则返回 */ return it.hasNext() ? finishToArray(r, it) : r; }
public <T> T[] toArray(T[] a) {}
public <T> T[] toArray(T[] a) { int size = size(); T[] r = a.length >= size ? a : /* 如果 a 的长度大于 size,直接使用 a */ (T[])java.lang.reflect.Array /* 如果 a 长度过小,new 一个新数组 */ .newInstance(a.getClass().getComponentType(), size); Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { /* 遍历 */ /* 下面这个判断为 true 的时机是: */ /* 多线程情况下,collection 数量在遍历过程中减少,提前终止 */ if (! it.hasNext()) { /* (a == r) => (a.length >= size) */ if (a == r) { /* a.length 本来就足够容纳 collection */ r[i] = null; /* 在结束处写入 null */ } else if (a.length < i) { /* 入参 a 的 length 太小,甚至无法容纳元素减少之后的 collection */ return Arrays.copyOf(r, i); /* 进行拷贝,返回一个新数组 */ } else { /* a.length 遍历前是不够大的,但是由于元素的减少量过多,目前又足够了,无需扩容了 */ System.arraycopy(r, 0, a, 0, i); /* 数值拷贝 */ if (a.length > i) { /* 如果有可能,末尾设置一个 null */ a[i] = null; } } return a; } r[i] = (T)it.next(); } return it.hasNext() ? finishToArray(r, it) : r; }
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {}
private static int hugeCapacity(int minCapacity) {}
当迭代器返回比预期更多的元素时,重新分配toArray中使用的数组,并从迭代器完成填充。其实就是扩容,数组长度不够,增加长度
private static <T> T[] finishToArray(T[] r, Iterator<?> it) { int i = r.length; while (it.hasNext()) { int cap = r.length; if (i == cap) { int newCap = cap + (cap >> 1) + 1; // overflow-conscious code if (newCap - MAX_ARRAY_SIZE > 0) //如果数组长度大于最大允许数组长度,则通过hugeCapacity方法重新获取一个合适的数组长度 newCap = hugeCapacity(cap + 1); //获取新的数组长度 r = Arrays.copyOf(r, newCap); } r[i++] = (T)it.next(); } // trim if overallocated return (i == r.length) ? r : Arrays.copyOf(r, i); } //返回新数组的长度 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError ("Required array size too large"); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
public boolean add(E e){ throw new UnsupportedOperationException(); } //AbstractCollection没有具体实现,调用抛出异常
public boolean remove(Object o) { } 这个方法实现比较简单
public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { it.remove(); return true; } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); return true; } } } return false; }
public boolean containsAll(Collection<?> c) {} //循环调用contain()方法。
public boolean addAll(Collection<? extends E> c) {} // 循环添加
public boolean removeAll(Collection<?> c) {} //循环删除指定集合
public boolean retainAll(Collection<?> c) {} //循环删除不在集合c中的元素
public void clear() {} //全部删除
以上是关于java源码 -- AbstractCollection抽象类的主要内容,如果未能解决你的问题,请参考以下文章