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

本文探讨了Java集合类库中的Collection接口,通过一张集合类的UML图展示了其结构。文章详细介绍了Collection接口的主要方法,包括新增的removeIf方法的默认实现。此外,还深入分析了AbstractCollection抽象类,特别是toArray方法的实现逻辑,包括无参和泛型参数版本,解释了不同情况下数组的创建和填充策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来一张Collection类的“全家福”,方便大家理解类与类之间的关系:

(集合类库UML图来自于http://blog.youkuaiyun.com/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方法,创建更大的数组并返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值