java集合类库学习记录———Collection类库的结构

来源:互联网 发布:java substring的用法 编辑:程序博客网 时间:2024/06/05 22:47
先来一张Collection类的“全家福”,方便大家理解类与类之间的关系:

(集合类库UML图来自于http://blog.csdn.net/vking_wang/article/details/16965853)
从图上可以看出来,集合大概可以分成2部分,一部分用Collection作为跟接口,另一部分用Map作为根接口。
我们先了解下Collection接口,Collection接口有方法(在1.8中新加入Stream方法,不作介绍):
可以注意到,接口中有一部分可选方法:add相关方法,clear,remove相关方法,retainAll方法。这些方法都会引起Collection结构发生改变。
Collection接口中给出了removeIf方法的默认实现:
    default boolean removeIf(Predicate<? super E> filter) {//给removeIf方法传递一个lambda表达式,表达式的内容为Predicate中test方法的实现        Objects.requireNonNull(filter);        boolean removed = false;        final Iterator<E> each = iterator();        while (each.hasNext()) {            if (filter.test(each.next())) {                each.remove();                removed = true;            }        }        return removed;    }

下面我们来看看Collection的抽象子类AbstractCollection,AbstractCollection是java自己提供的一个最基本的Collection的实现。当然它依然是一个抽象类。对于一个不可更改的集合,只要继承这个类并且实现迭代器和size()方法就行。
在此抽象类中,提供了一部分集合操作的通用实现,我们就来看看这些通用实现的其中两个:
    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);//集合中的对象数目少于Size()的数目            r[i] = it.next();        }        return it.hasNext() ? finishToArray(r, it) : r; //集合中的对象数目比Size()多时进入finishToArray方法,集合中对象数目与size    }
    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) {                    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;    }
toArray无参方法返回一个Object数组,它的思路如下:
1.创建一个估算的大小Object数组,并初始化一个迭代器
2.当集合中元素数量小于数组长度时,复制集合元素到数组并截断数组,最后返回数组。
3.当集合中元素数量大于数组长度时,创建更大的数组并复制集合元素,最后返回数组。
toArray泛型参数方法返回数组的运行时类型与指定数组的运行时类型相同,它的思路如下:
1.创建一个“大”数组(当输入数组长度大时就是输入数组,当size方法大时就创建新数组)。
2.当集合中的元素比创建的数组中的元素少,且输入数组长度“大“时,将集合元素放在数组中,并给集合元素后面的数组元素赋值为null;
3.当集合中的元素比创建的数组中的元素少且比传入的数组长度多时,将集合元素放在数组中,并截断数组返回。
4.当集合中的元素比创建的数组中的元素少且比传入的数组长度少时,将集合元素放在数组中,将数组复制给输入数组,输入数组的其余值为null,并返回。
5.当集合中的元素比创建的数组中的元素多时,用finishToArray方法,创建更大的数组并返回。

原创粉丝点击