Java AbstractCollection源码分析
2015-10-29 13:47
513 查看
<span style="font-size:14px;">public abstract class AbstractCollection<E> implements Collection<E> { /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected AbstractCollection() { } // Query Operations /** * Returns an iterator over the elements contained in this collection. * * @return an iterator over the elements contained in this collection */ public abstract Iterator<E> iterator(); public abstract int size(); /** * {@inheritDoc} * * <p>This implementation returns <tt>size() == 0</tt>. */ public boolean isEmpty() { return size() == 0; } /** * {@inheritDoc} * * <p>This implementation iterates over the elements in the collection, * checking each element in turn for equality with the specified element. * * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public boolean contains(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false; } /** * {@inheritDoc} * * <p>This implementation returns an array containing all the elements * returned by this collection's iterator, in the same order, stored in * consecutive elements of the array, starting with index {@code 0}. * The length of the returned array is equal to the number of elements * returned by the iterator, even if the size of this collection changes * during iteration, as might happen if the collection permits * concurrent modification during iteration. The {@code size} method is * called only as an optimization hint; the correct result is returned * even if the iterator returns a different number of elements. * * <p>This method is equivalent to: * * <pre> {@code * List<E> list = new ArrayList<E>(size()); * for (E e : this) * list.add(e); * return list.toArray(); * }</pre> */ public Object[] toArray() { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) // fewer elements than expected return Arrays.copyOf(r, i); r[i] = it.next(); } return it.hasNext() ? finishToArray(r, it) : r; } /** * {@inheritDoc} * * <p>This implementation returns an array containing all the elements * returned by this collection's iterator in the same order, stored in * consecutive elements of the array, starting with index {@code 0}. * If the number of elements returned by the iterator is too large to * fit into the specified array, then the elements are returned in a * newly allocated array with length equal to the number of elements * returned by the iterator, even if the size of this collection * changes during iteration, as might happen if the collection permits * concurrent modification during iteration. The {@code size} method is * called only as an optimization hint; the correct result is returned * even if the iterator returns a different number of elements. * * <p>This method is equivalent to: * * <pre> {@code * List<E> list = new ArrayList<E>(size()); * for (E e : this) * list.add(e); * return list.toArray(a); * }</pre> * * @throws ArrayStoreException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public <T> T[] toArray(T[] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); 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.hasNext()) { // fewer elements than expected if (a != r) return Arrays.copyOf(r, i); r[i] = null; // null-terminate return r; } r[i] = (T)it.next(); } return it.hasNext() ? finishToArray(r, it) : r; } /** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * Reallocates the array being used within toArray when the iterator * returned more elements than expected, and finishes filling it from * the iterator. * * @param r the array, replete with previously stored elements * @param it the in-progress iterator over this collection * @return array containing the elements in the given array, plus any * further elements returned by the iterator, trimmed to size */ 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) 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; } // Modification Operations /** * {@inheritDoc} * * <p>This implementation always throws an * <tt>UnsupportedOperationException</tt>. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ public boolean add(E e) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * * <p>This implementation iterates over the collection looking for the * specified element. If it finds the element, it removes the element * from the collection using the iterator's remove method. * * <p>Note that this implementation throws an * <tt>UnsupportedOperationException</tt> if the iterator returned by this * collection's iterator method does not implement the <tt>remove</tt> * method and this collection contains the specified object. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ 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; } // Bulk Operations /** * {@inheritDoc} * * <p>This implementation iterates over the specified collection, * checking each element returned by the iterator in turn to see * if it's contained in this collection. If all elements are so * contained <tt>true</tt> is returned, otherwise <tt>false</tt>. * * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @see #contains(Object) */ public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true; } /** * {@inheritDoc} * * <p>This implementation iterates over the specified collection, and adds * each object returned by the iterator to this collection, in turn. * * <p>Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is * overridden (assuming the specified collection is non-empty). * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} * * @see #add(Object) */ public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } /** * {@inheritDoc} * * <p>This implementation iterates over this collection, checking each * element returned by the iterator in turn to see if it's contained * in the specified collection. If it's so contained, it's removed from * this collection with the iterator's <tt>remove</tt> method. * * <p>Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> if the iterator returned by the * <tt>iterator</tt> method does not implement the <tt>remove</tt> method * and this collection contains one or more elements in common with the * specified collection. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * * @see #remove(Object) * @see #contains(Object) */ public boolean removeAll(Collection<?> c) { boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; } /** * {@inheritDoc} * * <p>This implementation iterates over this collection, checking each * element returned by the iterator in turn to see if it's contained * in the specified collection. If it's not so contained, it's removed * from this collection with the iterator's <tt>remove</tt> method. * * <p>Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> if the iterator returned by the * <tt>iterator</tt> method does not implement the <tt>remove</tt> method * and this collection contains one or more elements not present in the * specified collection. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * * @see #remove(Object) * @see #contains(Object) */ public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); modified = true; } } return modified; } /** * {@inheritDoc} * * <p>This implementation iterates over this collection, removing each * element using the <tt>Iterator.remove</tt> operation. Most * implementations will probably choose to override this method for * efficiency. * * <p>Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> if the iterator returned by this * collection's <tt>iterator</tt> method does not implement the * <tt>remove</tt> method and this collection is non-empty. * * @throws UnsupportedOperationException {@inheritDoc} */ public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } // String conversion /** * Returns a string representation of this collection. The string * representation consists of a list of the collection's elements in the * order they are returned by its iterator, enclosed in square brackets * (<tt>"[]"</tt>). Adjacent elements are separated by the characters * <tt>", "</tt> (comma and space). Elements are converted to strings as * by {@link String#valueOf(Object)}. * * @return a string representation of this collection */ public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); sb.append(',').append(' '); } } } </span>
以上是Java JDK中的AbstractCollection源码,其中包括的功能函数有:
1,protected 的构造函数。
protected AbstractCollection() { }
protected 修饰的类中属性和方法,可以在本类中使用,可以被其子类(即使不同包)使用,可以被同包中的其他类使用。
有个容易混淆的情况:
package 1;
class A{
protected int x;
}
package 2;
class B extends A{
x=2;//right
A a;
a.x;//wrong
}
注释:
Protected access requires a little more elaboration. Suppose class A declares a protected field x and is extended by a class B, which is defined in a different package (this last point is important). Class
B inherits the protected field x, and its code can access that field in the current instance of B or in any other instances of B that the code can refer to. This does not mean, however, that the code of class B can start reading the protected fields of arbitrary
instances of A! If an object is an instance of A but is not an instance of B, its fields are obviously not inherited by B, and the code of class B cannot read them.
更详细的信息参考:http://zhangjunhd.blog.51cto.com/113473/19287/
2,Iterator() & size()
public abstract Iterator<E> iterator(); public abstract int size();
虚拟函数,会在子孙类中实现。
3,isEmpty()
public boolean isEmpty() { return size() == 0; }判断是否为空,是根据所含元素数量
4,Contains()
public boolean contains(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false; }Iterator<E> it=iterator();生成此collection的迭代器,进行collection的遍历。
在判断是否包含某个Object o的时候,分为此o==null?用等号判断相等;用元素所在类的equals()方法判断相等。所以若存入其中的元素是自定义对象,则需要重写其equals()方法。
5,toArray()
public Object[] toArray() { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) // fewer elements than expected return Arrays.copyOf(r, i); r[i] = it.next(); } return it.hasNext() ? finishToArray(r, it) : r; }这个集合类型和数组类型连接转化的”桥梁“。在function中,先按size()值创造Object 数组 r, 然后创建迭代器对collection进行遍历,依次复制collection的每一个元素到数组r中,直到collection遍历到了头,此时,数组r中全部包含了collection中的元素。这个时候,通过复制r数组创建一个新数组,返回。
最好,以防在运行期间,collection的大小改变了。则判断it.hasNext()来确定是否遇到数组r的大小变得小与collection的大小情况,若是,则运行finishToArray()进行重新复制,否则,返回r.
6,toArray()
public <T> T[] toArray(T[] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); 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.hasNext()) { // fewer elements than expected if (a != r) return Arrays.copyOf(r, i); r[i] = null; // null-terminate return r; } r[i] = (T)it.next(); } return it.hasNext() ? finishToArray(r, it) : r; }
将collection的元素转化成array类型,并存放于T[] a中。
可见修饰符后的<T>是申明一个泛型T。函数的返回的值类型是T[]。
创建临时数组T[] r ,若指定数组a的大小大于等于collection的大小,则r 等于a;否则,a太小了,按照collection的大小重新创建数组给r。
若r没到最末,依次复制collection 元素到r中,直到collection到末尾。若r是新创建的数组即不等于a,则返回的是以r为模板创建的新数组;若r就是a则加上数组结束符号,返回r.(这里不知道解读可对,也不知为什么这样设计)
同样,也要考虑运行期间,万一collection的大小改变的情况。
7,finishToArray()
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
设定array最大能存储的size大小。具体为啥这样计算不是很清楚
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) 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); }
第一次,是i==cap ,进行扩大r的容量的操作,首先尝试夸1.5倍左右,然后判断是否超过了数组的最大容量限度。若超过,真通过hugeCapacity再次计算。
扩大r的容量后,开始依次复制collection的元素到数组里了。
最后返回r,此时r中的元素都是collection中的元素,否则r中有填充元素,则截取r中前i个元素,新建数组返回。
8,hugeCapacity()
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; }重新调整最大容量
9,remove()
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; }
remove删除collection中的一个object,首先分object是不是null,null通过==来判断相等,否则通过equals来判断内容相等。
10,containsAll()
public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true; }
判断是否包含 collection e 中的所有元素。<?>为泛型通配符,在宣告名称时如果指定了<?>而 不使用"extends",则预设是允许Object及其下的子类,也就是所有的Java对象了,那为什么不直接使用GenericFoo宣告就好了,何 必要用GenericFoo<?>来宣告?使用通配字符有点要注意的是,透过使用通配字符宣告的名称所参考的对象,您没办法再对它加入新的资 讯,您只能取得它的信息或是移除它的信息,关于泛型通配符的使用参考 http://www.iteedu.com/plang/java/javadiary/70.php 还不清楚此知识点,有待进一步学习
11,AddAll()
public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; }
将一个新的collection c全部写到原collection中,只要原collection有状态改变,即返回true.增加成功与否,还要依赖add的具体实现,
12,removeAll()
public boolean removeAll(Collection<?> c) { boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; }
从原collection中删除c中的元素,通过contains元素来判断c中是否存在某个元素,是的话,从原collection中删除该元素。
13,retainAll()
public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); modified = true; } } return modified; }
只保留即在c中也在原collection中的元素。方法和removeAll()相似,只是在判断条件上,删除的是不在c的元素。
14,clear()
public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } }
通过迭代器,依次遍历collection中元素,依次删除。
15,toString()
public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); sb.append(',').append(' '); } }
返回这个collection的string表现形式,会将元素放到【】中,通过逗号“,”区分各元素。但是为什么会有个e==this的判断,还不清楚。
若有不对之处,希望得到你的指导更正。
相关文章推荐
- 常见小算法集合
- java的转义字符
- 如何写出好的Java代码
- java 获取系统时间
- Java的引用类型
- Eclipse中项目的导入和导出
- Java的异常体系
- Java内存分配
- Java中的内存泄露问题
- java核心技术细语解读易忽视点(一)(1-3章)
- Java的单例模式
- Java编程思想 - 第7章、复用类
- PL/SQL 调用JAVA使用UDP发送数据
- eclipse pdt下载
- Java ClassLoader深入讲解
- 解决Spring Security 开启remember-me(持久化),session并发控制后重启服务器remember-me持久化凭证消失问题
- 细说JAVA反射
- Java Collections.addAll() 与 ArrayList.addAll() 的区别
- JAVA泛型——逆变
- spring security4 security="none"小讲