java.util源码之AbstractCollection(基于jdk1.7)

public Object[] toArray() {
        // 转成数组,同时考虑在执行该方法时,有其他线程删除Collection中元素和向Collection插入数据的情况
        Object[] r = new Object[size()];
        Iterator<E> it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // 在当前线程调用该方法时,另外的线程调用this.remove或者iterator.remove
                return Arrays.copyOf(r, i);    //返回数组的长度为i,也就是实际大小
            r[i] = it.next();
        }
//在当前线程调用该方法时,另外的线程调用this.add或者iterator.add时,it.hasNext为true,执行finishToArray,当没有其他的线程调用add(iterator.add), remove(iterator.remove)时,返回r
        return it.hasNext() ? finishToArray(r, it) : r; 
}

//将执行toArray的结果写入传递过来的参数中
public <T> T[] toArray(T[] a) {    int size = size();    //如果参数数组长度>=Collection容量,返回参数数组,否则返回new出来的java.lang.reflect.Array,大小为Collection本身容量
    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) {  //当参数数组长度>=Collection容量时
                r[i] = null; // null-terminate            } 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();    }    // more elements than expected    return it.hasNext() ? finishToArray(r, it) : r;}
 
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {    int i = r.length;    while (it.hasNext()) {        int cap = r.length;        if (i == cap) {   
//每次当索引值指向数组的最后一个元素+1时以右移1位+1的速度进行扩容,如11扩容成11+11/2+1=17//执行ArrayList add方法时,当数组长度不够时,以右移1位的速度进行扩容,如11扩容成11+11/2=16//在执行toArray时,为什么要加1,我不太明白??????
            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();  //因为i初使值为r.length, 所以i++而不是++i    }    // 为提高效率,当while执行完成时,如果索引值恰好位于数组末端+1时,直接返回r    //其实return (i != r.length ? Arrays.copyOf(r, i) : r)效率更高,因为i==r.length的情况非常态,特别当数组很大的时候    return (i == r.length) ? r : Arrays.copyOf(r, i);}
 
时间: 2024-11-09 04:43:30

java.util源码之AbstractCollection(基于jdk1.7)的相关文章

java基础系列之ConcurrentHashMap源码分析(基于jdk1.8)

1.前提 在阅读这篇博客之前,希望你对HashMap已经是有所理解的,否则可以参考这篇博客: jdk1.8源码分析-hashMap:另外你对java的cas操作也是有一定了解的,因为在这个类中大量使用到了cas相关的操作来保证线程安全的. 2.概述 ConcurrentHashMap这个类在java.lang.current包中,这个包中的类都是线程安全的.ConcurrentHashMap底层存储数据的结构与1.8的HashMap是一样的,都是数组+链表(或红黑树)的结构.在日常的开发中,我们

HashMap源码分析(基于JDK1.6)

在Java集合类中最常用的除了ArrayList外,就是HashMap了.本文尽自己所能,尽量详细的解释HashMap的源码.一山还有一山高,有不足之处请之处,定感谢指定并及时修正. 在看HashMap源码之前先复习一下数据结构. Java最基本的数据结构有数组和链表.数组的特点是空间连续(大小固定).寻址迅速,但是插入和删除时需要移动元素,所以查询快,增加删除慢.链表恰好相反,可动态增加或减少空间以适应新增和删除元素,但查找时只能顺着一个个节点查找,所以增加删除快,查找慢.有没有一种结构综合了

ArrayList源码阅读笔记(基于JDk1.8)

关键常量: private static final int DEFAULT_CAPACITY = 10; 当没有其他参数影响数组大小时的默认数组大小 private static final Object[] EMPTY_ELEMENTDATA = {}; 如果elementData用这个变量初始化,则DEFAULT_CAPACITY不会参与数组大小的运算 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

【Java集合源码剖析】HashMap源码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955 HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap. HashMap 实现了Serializable接口,因此它支持序列化,

Java集合源码分析(四)Vector&lt;E&gt;

Vector<E>简介 Vector也是基于数组实现的,是一个动态数组,其容量能自动增长. Vector是JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(其实也只是相对安全,有些时候还是要加入同步语句来保证线程的安全),可以用于多线程环境. Vector没有丝线Serializable接口,因此它不支持序列化,实现了Cloneable接口,能被克隆,实现了RandomAccess接口,支持快速随机访问. Vector<E>源码 如下(已加入详细注释): /*

Java集合源码分析(二)ArrayList

ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类. ArrayList实现了Serializable接口,因此它支持序列化,能够通过

Java集合源码分析(三)LinkedList

LinkedList简介 LinkedList是基于双向循环链表(从源码中可以很容易看出)实现的,除了可以当做链表来操作外,它还可以当做栈.队列和双端队列来使用. LinkedList同样是非线程安全的,只在单线程下适合使用. LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆. LinkedList源码 以下是linkedList源码(加入简单代码注释): /* * @(#)LinkedList.java 1.6

【Java集合源码剖析】Vector源码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/35793865 Vector简介 Vector也是基于数组实现的,是一个动态数组,其容量能自动增长. LinkedList是JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(其实也只是相对安全,有些时候还是要加入同步语句来保证线程的安全),可以用于多线程环境. LinkedList没有丝线Serializable接口,因此它不支持序列化,实现了Cloneable接口,

【Java集合源码剖析】HashMap源码剖析(转)

HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap. HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆. HashMap源码剖析 HashMap的源码如下(加入了比较详细的注释): [ja