JAVA集合一 ——集合结构

来源:互联网 发布:vue.js教程 编辑:程序博客网 时间:2024/06/15 13:10


JAVA集合一 ——集合整体接口


     特别声明:

     *本文只是备忘录。

     JAVA中集合是一个很重要的概念,首先来看看整体的类图。

    集合的主要接口为collection。Collection 继承自Iterable接口,而Iterable接口封装了生成迭代器的方法Iterator()。这样所有集合都需要实现该方法,这也是java设计模式中的迭代器模式。

      由图中可以看出集合的几个主要的子接口为:List、Set、Queue。一个抽象实现类 AbstractCollection。

      List、Set、Queue接口后面分析。先来看AbstractCollection。

     AbstractCollection 主要是提供了一些Collection接口的方法的实现。

    主要看一下 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;    }

    将集合中的元素复制到数组中。看看最后返回的是什么?最后为什么还要判断it.hasNext()?

     能产生这种问题的情况,多线程!。

     在来看看 finishToArray()的源码:

    

 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);    }
    第一步扩容
    扩容的算法,每次扩容原先容量的一半+1。
int newCap = cap + (cap >> 1) + 1;
    第二步
    如果扩容后的值大于集合定义的最大值,则表示数组太大,如果一次性扩容会占用很多内存。需要重新扩容。通过传入cap+1来生成一个合适的新值。
if (newCap - MAX_ARRAY_SIZE > 0)                    newCap = hugeCapacity(cap + 1);
 
    private static int hugeCapacity(int minCapacity) {
        //该处判断上面的cap + 1是否已经超出了int的最大值。        if (minCapacity < 0) // overflow            throw new OutOfMemoryError                ("Required array size too large");
//判断扩容后的值是否大于数组的最大size,如果大于返回INT的最大值。否则返回定义的最大值        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE :MAX_ARRAY_SIZE;    }
看看集合定义的最大值是多少:
   private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

     

      再来看看List、Set、Queue接口。

      List:定义的是有序的集合,允许元素的重复。允许多个null。

      Set:定义的是不能重复的集合,可以有null,但是只能有一个。Set分有序和无需的。TreeSet:有序,hashSet:无需。

      Queue: 定义的是"队列"先进先出(FIFO)的数据结构。不允许随机访问。

      后面会具体分析。


0 0
原创粉丝点击